Table of Contents
This section documents all the generic methods available in the Technique Editor.
Execute a command
Compatible with nodes running Rudder 4.1 or higher.
- command_name: Command name
command_execution_${command_name}_{kept, repaired, not_ok, reached}
Execute a command and create outcome classes depending on its exit code
Compatible with nodes running Rudder 4.1 or higher.
Execute a command and create outcome classes depending on the exit codes given in parameters. If an exit code is not in the list it will lead to an error status. If you want 0 to be a success you have to list it in the kept_codes list
- command: The command to run
- kept_codes: List of codes that produce a kept status separated with commas (ex: 1,2,5)
- repaired_codes: List of codes that produce a repaired status separated with commas (ex: 3,4,6)
command_execution_result_${command}_{kept, repaired, not_ok, reached}
Execute a command and create outcome classes depending on its exit code
Compatible with nodes running Rudder 4.1 or higher.
This method executes a command, and defines a ${condition_prefix}_true
or a ${condition_prefix}_false
condition depending on the result of
the command:
-
If the exit code is in the
true_codes
list, this will produce a kept outcome class and a${condition_prefix}_true
condition -
If the exit code is in the
false_codes
list, this will produce a repaired outcome class and a${condition_prefix}_false
condition -
If the exit code is not in the list, or if the command is not present,
this will produce an error outcome class and no classes with
${condition_prefix}
The created condition is global to the agent.
If you run a command /bin/check_network_status
that output code 0, 1
or 2 in case of correct configuration, and 18 or 52 in case of invalid
configuration, and you want to get this define a condition based on this
command, you can use the following policy
condition_from_command("network_correctly_defined", "/bin/check_network_status", "0,1,2", "18,52")
-
If the command exits 0, 1 or 2, then it will define the following
conditions
network_correctly_defined_true
,condition_from_command_network_correctly_defined_kept
,condition_from_command_network_correctly_defined_reached
-
If the command exits 18, 52, then it will define the following
conditions
network_correctly_defined_false
,condition_from_command_network_correctly_defined_kept
,condition_from_command_network_correctly_defined_reached
-
If the command exits any other code, then it will define the following
conditions
condition_from_command_network_correctly_defined_error
,condition_from_command_network_correctly_defined_reached
-
Finally, if the command is not present on the node, it will define
condition_from_command_network_correctly_defined_error
,condition_from_command_network_correctly_defined_reached
- condition_prefix: The condition name
- command: The command to run
- true_codes: List of codes that produce a true status separated with commas (ex: 1,2,5)
- false_codes: List of codes that produce a false status separated with commas (ex: 3,4,6)
condition_from_command_${condition_prefix}_{kept, repaired, not_ok, reached}
Create a new condition class
Compatible with nodes running Rudder 4.1 or higher.
This method evaluates an expression, and produces a
${condition_prefix}_true
or a ${condition_prefix}_false
condition
depending on the result on the expression:
-
If the expression results in a "defined" state, this will produce a
kept outcome class and a
${condition_prefix}_true
condition -
If the expression results in an "undefined" state, this will produce a
kept outcome class and a
${condition_prefix}_false
condition
Calling this method with a condition expression transforms a complex expression into a single class condition.
The created condition is global to the agent.
If you want to check if a condition evaluates to true, like checking that you are on Monday, 2am, on RedHat systems, you can use the following policy
condition_from_expression("backup_time", "Monday.redhat.Hr02")
-
If the system is a RedHat like system, on Monday, at 2am, then it will
define the following conditions
backup_time_true
,condition_from_expression_backup_time_kept
,condition_from_expression_backup_time_reached
-
If the system not a RedHat like system, or it’s not Monday, or it’s
not 2am, then it will define the following conditions
backup_time_false
,condition_from_expression_backup_time_kept
,condition_from_expression_backup_time_reached
-
If the condition is invalid (cannot be parsed), it will define only
condition_from_expression_backup_time_kept
,condition_from_expression_backup_time_reached
- condition_prefix: The condition prefix
- condition_expression: The expression evaluated to create the condition (use any to always evaluate to true)
condition_from_expression_${condition_prefix}_{kept, repaired, not_ok, reached}
Create a new condition class that persists across runs
Compatible with nodes running Rudder 4.1 or higher.
This method evaluates an expression, and produces a
${condition_prefix}_true
or a ${condition_prefix}_false
condition
depending on the result on the expression, that lasts for the duration
time:
-
If the expression results in a "defined" state, this will produce a
kept outcome class and a
${condition_prefix}_true
condition -
If the expression results in an "undefined" state, this will produce a
kept outcome class and a
${condition_prefix}_false
condition
Calling this method with a condition expression transforms a complex expression into a single class condition.
The created condition is global to the agent and is persisted across
runs. The persistence duration is controlled using ${duration}
; it
defines for how long the resulting condition will be defined (in
minutes). Note that there is no way to persist indefinitely.
If you want to check if a condition evaluates to true, like checking that you are on Monday, 2am, on RedHat systems, and make it last one hour you can use the following policy
condition_from_expression_persistent_("backup_time", "Monday.redhat.Hr02", "60")
-
If the system is a RedHat like system, on Monday, at 2am, then it will
define the following conditions
backup_time_true
,condition_from_expression_persistent_backup_time_kept
,condition_from_expression_persistent_backup_time_reached
-
If the system not a RedHat like system, or it’s not Monday, or it’s
not 2am, then it will define the following conditions
backup_time_false
,condition_from_expression_persistent_backup_time_kept
,condition_from_expression_persistent_backup_time_reached
-
If the condition is invalid (cannot be parsed), it will define only
condition_from_expression_persistent_backup_time_kept
,condition_from_expression_persistent_backup_time_reached
- condition_prefix: The condition prefix
- condition_expression: The expression evaluated to create the condition (use any to always evaluate to true)
- duration: The persistence suffix in minutes
condition_from_expression_persistent_${condition_prefix}_{kept, repaired, not_ok, reached}
Ensure a directory’s absence
Compatible with nodes running Rudder 4.1 or higher.
If recursive
is false, only an empty directory can be deleted.
- target: Directory to remove
- recursive: Should deletion be recursive, "true" or "false" (defaults to "false")
directory_absent_${target}_{kept, repaired, not_ok, reached}
Checks if a directory exists
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
directory_check_exists_${directory_name}_{ok, reached, kept}
if the
directory exists, or
directory_check_exists_${directory_name}_{not_ok, reached, not_kept, failed}
if the directory doesn’t exists
- directory_name: Full path of the directory to check
directory_check_exists_${directory_name}_{kept, repaired, not_ok, reached}
Enforce an environment variable value. Caution, the new environment variable will not be usable by the agent until it is restarted
Compatible with nodes running Rudder 4.1 or higher.
- name: Name of the environment variable
- value: Value of the environment variable
environment_variable_present_${name}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a FIFO/Pipe
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_FIFO_pipe_${file_name}_{ok, reached, kept}
if the file is a
FIFO, or
file_check_FIFO_pipe_${file_name}_{not_ok, reached, not_kept, failed}
if the file is not a fifo or does not exist
- file_name: File name (absolute path on the target node)
file_check_FIFO_pipe_${file_name}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a block device
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_block_device_${file_name}_{ok, reached, kept}
if the file
is a block_device, or
file_check_block_device_${file_name}_{not_ok, reached, not_kept, failed}
if the file is not a block device or does not exist
- file_name: File name (absolute path on the target node)
file_check_block_device_${file_name}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a character device
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_character_device_${file_name}_{ok, reached, kept}
if the
file is a character device, or
file_check_character_device_${file_name}_{not_ok, reached, not_kept, failed}
if the file is not a character device or does not exist
- file_name: File name (absolute path on the target node)
file_check_character_device_${file_name}_{kept, repaired, not_ok, reached}
Checks if a file exists
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_exists_${file_name}_{ok, reached, kept}
if the file exists,
or file_check_exists_${file_name}_{not_ok, reached, not_kept, failed}
if the file doesn’t exists
- file_name: File name (absolute path on the target node)
file_check_exists_${file_name}_{kept, repaired, not_ok, reached}
Checks if two files are the same (hard links)
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_hardlink_${file_name_1}_{ok, reached, kept}
if the two
files ${file_name_1}
and ${file_name_2}
are hard links of each
other, or
file_check_hardlink_${file_name_1}_{not_ok, reached, not_kept, failed}
if if the files are not hard links.
- file_name_1: File name #1 (absolute path on the target node)
- file_name_2: File name #2 (absolute path on the target node)
file_check_hardlink_${file_name_1}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a regular file
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_regular_${file_name}_{ok, reached, kept}
if the file is a
regular_file, or
file_check_regular_${file_name}_{not_ok, reached, not_kept, failed}
if
the file is not a regular file or does not exist
- file_name: File name (absolute path on the target node)
file_check_regular_${file_name}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a socket
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_socket_${file_name}_{ok, reached, kept}
if the file is a
socket, or
file_check_socket_${file_name}_{not_ok, reached, not_kept, failed}
if
the file is not a socket or does not exist
- file_name: File name (absolute path on the target node)
file_check_socket_${file_name}_{kept, repaired, not_ok, reached}
Checks if a file exists and is a symlink
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_symlink_${file_name}_{ok, reached, kept}
if the file is a
symlink, or
file_check_symlink_${file_name}_{not_ok, reached, not_kept, failed}
if
the file is not a symlink or does not exist
- file_name: File name (absolute path on the target node)
file_check_symlink_${file_name}_{kept, repaired, not_ok, reached}
Checks if first file is symlink to second file
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
file_check_symlinkto_${target}_{ok, reached, kept}
if the file
${symlink}
is a symbolic link to ${target}
, or
file_check_symlinkto_${target}_{not_ok, reached, not_kept, failed}
if
if it is not a symbolic link, or any of the files does not exist. The
symlink’s path is resolved to the absolute path and checked against the
target file’s path, which must also be an absolute path.
- symlink: Symbolic link (absolute path on the target node)
- target: Target file (absolute path on the target node)
file_check_symlinkto_${symlink}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is copied from a local source
Compatible with nodes running Rudder 4.1 or higher.
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_copy_from_local_source_${destination}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is copied from a local source
Compatible with nodes running Rudder 4.1 or higher.
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
- recursion: Recursion depth to enforce for this path (0, 1, 2, …, inf)
file_copy_from_local_source_${destination}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is copied from a local source if a check command succeeds
Compatible with nodes running Rudder 4.1 or higher.
This method is a conditionnal file copy.
It allows comparing the source and destination, and if they are different, call a command with the source file path as argument, and only update the destination if the commands succeeds (i.e. returns a code included in rc_ok).
# To copy a configuration file only if it passes a config test: file_copy_from_local_source_with_check("/tmp/program.conf", "/etc/program.conf", "program --config-test", "0");
This will:
-
Compare
/tmp/program.conf
and/etc/program.conf
, and returnkept
if files are the same -
If not, it will execute
program --config-test "/tmp/program.conf"
and check the return code -
If it is one of the
rc_ok
codes, it will copy/tmp/program.conf
into/etc/program.conf
and return a repaired - If not, it will return an error
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
- check_command: Command to run, it will get the source path as argument
- rc_ok: Return codes to be considered as valid, separated by a comma (default is 0)
file_copy_from_local_source_with_check_${destination}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is copied from a policy server
Compatible with nodes running Rudder 4.1 or higher.
Note: This method uses CFEngine file copy protocol, and can only download files from the policy server. To download a file from an external source, you can use HTTP with the file_download method.
This method requires that the policy server is configured to accept copy of the source file from the agents it will be applied to.
You have to write the full path of the file on the policy server, for example:
/home/myuser/myfile
If you are using Rudder, you can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_FILE
- source: Source file (absolute path on the policy server)
- destination: Destination file (absolute path on the target node)
file_copy_from_remote_source_${destination}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is copied from a policy server
Compatible with nodes running Rudder 4.1 or higher.
This method requires that the policy server is configured to accept copy of the source file or directory from the agents it will be applied to.
You have to write the full path of the file or directory on the policy server, for example:
/home/myuser/mydirectory
If you are using Rudder, you can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_DIRECTORY_OR_FILE
- source: Source file (absolute path on the policy server)
- destination: Destination file (absolute path on the target node)
- recursion: Recursion depth to enforce for this path (0, 1, 2, …, inf)
file_copy_from_remote_source_${destination}_{kept, repaired, not_ok, reached}
Create a file if it doesn’t exist
Compatible with nodes running Rudder 4.1 or higher.
- target: File to create (absolute path on the target node)
file_create_${target}_{kept, repaired, not_ok, reached}
Create a symlink at a destination path and pointing to a source target except if a file or directory already exists.
Compatible with nodes running Rudder 4.1 or higher.
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_create_symlink_${destination}_{kept, repaired, not_ok, reached}
Create a symlink at a destination path and pointing to a source target. This is also possible to enforce its creation
Compatible with nodes running Rudder 4.1 or higher.
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
- enforce: Force symlink if file already exist (true or false)
file_create_symlink_${destination}_{kept, repaired, not_ok, reached}
Create a symlink at a destination path and pointing to a source target even if a file or directory already exists.
Compatible with nodes running Rudder 4.1 or higher.
- source: Source file (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_create_symlink_${destination}_{kept, repaired, not_ok, reached}
Download a file if it does not exist, using curl with a fallback on wget
Compatible with nodes running Rudder 4.1 or higher.
This method finds a HTTP command-line tool and downloads the given source into the destination.
It tries curl
first, and wget
as fallback.
- source: URL to download from
- destination: File destination (absolute path on the target node)
file_download_${destination}_{kept, repaired, not_ok, reached}
Enforce the content of a file
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- lines: Line(s) to add in the file - if lines is a list, please use @{lines} to pass the iterator rather than iterating over each values
- enforce: Enforce the file to contain only line(s) defined (true or false)
file_ensure_lines_present_${file}_{kept, repaired, not_ok, reached}
Ensure that a section contains exactly a text block
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- section_start: Start of the section
- section_end: End of the section
- block: Block representing the content of the section
file_ensure_block_in_section_${file}_{kept, repaired, not_ok, reached}
Ensure that a text block is present in a specific location
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- block: Block(s) to add in the file
file_ensure_block_present_${file}_{kept, repaired, not_ok, reached}
Ensure that the file contains a pair of "key separator value"
Compatible with nodes running Rudder 4.1 or higher.
Edit (or create) the file, and ensure it contains an entry key → value with arbitrary separator between the key and its value. If the key is already present, the method will change the value associated with this key.
- file: File name to edit (absolute path on the target node)
- key: Key to define
- value: Value to define
- separator: Separator between key and value, for example "=" or " " (without the quotes)
file_ensure_key_value_${file}_{kept, repaired, not_ok, reached}
Ensure that the file contains a pair of "key separator value", with options on the spacing around the separator
Compatible with nodes running Rudder 4.1 or higher.
Edit (or create) the file, and ensure it contains an entry key → value with arbitrary separator between the key and its value. If the key is already present, the method will change the value associated with this key.
- file: File name to edit (absolute path on the target node)
- key: Key to define
- value: Value to define
- option: Option for the spacing around the separator: strict, which prevent spacings (space or tabs) around separators, or lax which accepts any number of spaces around separators
- separator: Separator between key and value, for example "=" or " " (without the quotes)
file_ensure_key_value_${file}_{kept, repaired, not_ok, reached}
Ensure that one parameter exists in a list of parameters, on one single line, in the right hand side of a key→values line
Compatible with nodes running Rudder 4.1 or higher.
Edit the file, and ensure it contains the defined parameter in the list of values on the right hand side of a key→values line. If the parameter is not there, it will be added at the end, separated by parameter_separator. Optionnaly, you can define leading and closing character to enclose the parameters If the key does not exist in the file, it will be added in the file, along with the parameter
If you have an initial file (/etc/default/grub
) containing
GRUB_CMDLINE_XEN="dom0_mem=16G"
To add parameter dom0_max_vcpus=32
in the right hand side of the line,
you’ll need the following policy
file_ensure_key_value_parameter_in_list("/etc/default/grub", "GRUB_CMDLINE", "=", "dom0_max_vcpus=32", " ", "\"", "\"");
- file: File name to edit (absolute path on the target node)
- key: Full key name
- key_value_separator: character used to separate key and value in a key-value line
- parameter: String representing the sub-value to ensure is present in the list of parameters that form the value part of that line
- parameter_separator: Character used to separate parameters in the list
- leading_char_separator: leading character of the parameters
- closing_char_separator: closing character of the parameters
file_ensure_key_value_parameter_in_list_${file}_{kept, repaired, not_ok, reached}
Ensure that a parameter doesn’t exist in a list of parameters, on one single line, in the right hand side of a key→values line
Compatible with nodes running Rudder 4.1 or higher.
Edit the file, and ensure it does not contain the defined parameter in the list of values on the right hand side of a key→values line. If the parameter is there, it will be removed. Please note that the parameter can be a regular expression. It will also remove any whitespace character between the parameter and parameter_separator Optionnaly, you can define leading and closing character to enclose the parameters
If you have an initial file (/etc/default/grub
) containing
GRUB_CMDLINE_XEN="dom0_mem=16G dom0_max_vcpus=32"
To remove parameter dom0_max_vcpus=32
in the right hand side of the
line, you’ll need the following policy
file_ensure_key_value_parameter_not_in_list("/etc/default/grub", "GRUB_CMDLINE", "=", "dom0_max_vcpus=32", " ", "\"", "\"");
- file: File name to edit (absolute path on the target node)
- key: Full key name
- key_value_separator: character used to separate key and value in a key-value line
- parameter_regex: Regular expression matching the sub-value to ensure is not present in the list of parameters that form the value part of that line
- parameter_separator: Character used to separate parameters in the list
- leading_char_separator: leading character of the parameters
- closing_char_separator: closing character of the parameters
file_ensure_key_value_parameter_not_in_list_${file}_{kept, repaired, not_ok, reached}
Ensure that a key-value pair is present in a section in a specific location. The objective of this method is to handle INI-style files.
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- section: Name of the INI-style section under which the line should be added or modified (not including the [] brackets)
- name: Name of the key to add or edit
- value: Value of the key to add or edit
file_ensure_key_value_present_in_ini_section_${file}_{kept, repaired, not_ok, reached}
Ensure that the file contains all pairs of "key separator value", with arbitrary separator between each key and its value
Compatible with nodes running Rudder 4.1 or higher.
This method ensures key-value pairs are present in a file.
This method will iterate over the key-value pairs in the dict, and:
- If the key is not defined in the destination, add the key separator + value line.
- If the key is already present in the file, replace the key separator + anything by key + separator + value
This method always ignores spaces and tabs when replacing (which means
for example that key = value
will match the =
separator).
Keys are considered unique (to allow replacing the value), so you should use file_ensure_lines_present if you want to have multiple lines with the same key.
If you have an initial file (/etc/myfile.conf
) containing:
key1 = something key3 = value3
To define key-value pairs, use the variable_dict or variable_dict_from_file methods.
For example, if you use the following content (stored in
/tmp/data.json
):
{ "key1": "value1", "key2": "value2" }
With the following policy:
# Define the `content` variable in the `configuration` prefix from the json file variable_dict_from_file("configuration", "content", "/tmp/data.json") # Enforce the presence of the key-value pairs file_ensure_keys_values("/etc/myfile.conf", "configuration.content", " = ")
The destination file (/etc/myfile.conf
) will contain:
key1 = value1 key3 = value3 key2 = value2
- file: File name to edit (absolute path on the target node)
- keys: Name of the dict structure (without "${}") containing the keys (keys of the dict), and values to define (values of the dict)
- separator: Separator between key and value, for example "=" or " " (without the quotes)
file_ensure_keys_values_${file}_{kept, repaired, not_ok, reached}
Ensure that a line is present in a section in a specific location. The objective of this method is to handle INI-style files.
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- section: Name of the INI-style section under which lines should be added (not including the [] brackets)
- line: Line to ensure is present inside the section
file_ensure_line_present_in_ini_section_${file}_{kept, repaired, not_ok, reached}
Ensure that a line is present in a tag in a specific location. The objective of this method is to handle XML-style files. Note that if the tag is not present in the file, it won’t be added, and the edition will fail.
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- tag: Name of the XML tag under which lines should be added (not including the <> brackets)
- line: Line to ensure is present inside the section
file_ensure_line_present_in_xml_tag_${file}_{kept, repaired, not_ok, reached}
Ensure that a line is absent in a specific location
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- lines: Line(s) to remove in the file
file_ensure_lines_absent_${file}_{kept, repaired, not_ok, reached}
Ensure that one or more lines are present in a file
Compatible with nodes running Rudder 4.1 or higher.
- file: File name to edit (absolute path on the target node)
- lines: Line(s) to add in the file
file_ensure_lines_present_${file}_{kept, repaired, not_ok, reached}
Build a file from a mustache string
Compatible with nodes running Rudder 4.1 or higher.
- template: String containing a template to be expanded
- destination: Destination file (absolute path on the target node)
file_from_string_mustache_${destination}_{kept, repaired, not_ok, reached}
Build a file from a legacy CFEngine template
Compatible with nodes running Rudder 4.1 or higher.
See file_from_template_type for general documentation about templates usage.
- source_template: Source file containing a template to be expanded (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_from_template_${destination}_{kept, repaired, not_ok, reached}
Build a file from a jinja2 template
Compatible with nodes running Rudder 4.1 or higher.
See file_from_template_type for general documentation about templates usage.
This generic method will build a file from a jinja2 template using data (classes and variables) found in the execution context.
It requires to have the jinja2 python module installed on the node, it
can usually be done in ncf with
package_present("python-jinja2", "", "", "")
.
![]() | Warning |
---|---|
If you are using a jinja2 version older than 2.7 trailing newlines will not be preserved in the destination file. |
Jinja2 is a powerful templating language, running in Python. The Jinja2 syntax reference documentation is http://jinja.pocoo.org/docs/dev/templates/ which will likely be useful, as Jinja2 is very rich and allows a lot more that what is explained here.
This section presents some simple cases that cover what can be done with mustache templating, and the way the agent data is provided to the templating engine.
The main specificity of jinja2 templating is the use of two root containers:
-
classes
to access currently defined classes -
vars
to access all currently defined variables
Note: You can add comments in the template, that will not be rendered in
the output file with {# ... #}
.
You can extend the Jinja2 templating engine by adding custom FILTERS and
TESTS in the script
/var/rudder/configuration-repository/ncf/10_ncf_internals/modules/templates/jinja2_custom.py
For instance, to add a filter to upperstring a string and a test if a
number is odd, you can create the file
/var/rudder/configuration-repository/ncf/10_ncf_internals/modules/extensions/jinja2_custom.py
on your Rudder server with the following content:
def upperstring(input): return input.upper() def odd(value): return True if (value % 2) else False FILTERS = {'upperstring': upperstring} TESTS = {'odd': odd}
These filters and tests will be usable in your jinja templates automatically.
To display content based on classes definition:
{% if classes.my_class is defined %} display this if defined {% endif %} {% if not classes.my_class is defined %} display this if not defined {% endif %}
Note: You cannot use class expressions here.
You can also use other tests, for example other bilt-in ones or those
defined in jinja2_custom.py
:
{% if vars.variable_prefix.my_number is odd %} display if my_number is odd {% endif %}
Here is how to display a scalar variable value (integer, string, …),
if you have defined
variable_string("variable_prefix", "my_variable", "my_value")
:
{{ vars.variable_prefix.my_variable }}
You can also modify what is displayed by using filters. The built-in
filters can be extended in jinja2_custom.py
:
{{ vars.variable_prefix.my_variable | upperstring }}
Will display the variable in uppercase.
To iterate over a list, for example defined with:
variable_iterator("variable_prefix", "iterator_name", "a,b,c", ",")
Use the following file:
{% for item in vars.variable_prefix.iterator_name %} {{ item }} is the current iterator_name value {% endfor %}
Which will be expanded as:
a is the current iterator_name value b is the current iterator_name value c is the current iterator_name value
To iterate over a container defined by the following json file, loaded
with variable_dict_from_file("variable_prefix", "dict_name", "path")
:
{ "hosts": [ "host1", "host2" ], "files": [ {"name": "file1", "path": "/path1", "users": [ "user1", "user11" ] }, {"name": "file2", "path": "/path2", "users": [ "user2" ] } ], "properties": { "prop1": "value1", "prop2": "value2" } }
Use the following template:
{% for item in vars.variable_prefix.dict_name.hosts %} {{ item }} is the current hosts value {% endfor %} # will display the name and path of the current file {% for file in vars.variable_prefix.dict_name.files %} {{ file.name }}: {{ file.path }} {% endfor %} # will display the users list of each file {% for file in vars.variable_prefix.dict_name.files %} {{ file.name }}: {{ file.users|join(' ') }} {% endfor %} # will display the current properties key/value pair {% for key, value in vars.variable_prefix.dict_name.properties.items() %} {{ key }} -> {{ value }} {% endfor %}
Which will be expanded as:
host1 is the current hosts value host2 is the current hosts value # will display the name and path of the current file file1: /path1 file2: /path2 # will display the users list of each file file1: user1 user11 file2: user2 # will display the current properties key/value pair prop1 -> value1 prop2 -> value2
- source_template: Source file containing a template to be expanded (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_from_template_${destination}_{kept, repaired, not_ok, reached}
Build a file from a mustache template
Compatible with nodes running Rudder 4.1 or higher.
See file_from_template_type for general documentation about templates usage.
Mustache is a logic-less templating language, available in a lot of languages, and used for file templating in CFEngine. The mustache syntax reference is https://mustache.github.io/mustache.5.html.
We will here describe the way to get agent data into a template. Ass explained in the general templating documentation, we can access various data in a mustache template.
The main specificity compared to standard mustache syntax of prefixes in all expanded values:
-
classes
to access classes -
vars
to access all variables
Here is how to display content depending on classes definition:
{{#classes.my_class}} content when my_class is defined {{/classes.my_class}} {{^classes.my_class}} content when my_class is *not* defined {{/classes.my_class}}
Note: You cannot use class expressions here.
Here is how to display a scalar variable value (integer, string, …),
if you have defined
variable_string("variable_prefix", "my_variable", "my_value")
:
{{{vars.variable_prefix.my_variable}}}
We use the triple {{{ }}}
to avoid escaping html entities.
Iteration is done using a syntax similar to scalar variables, but applied on container variables.
-
Use
{{#vars.container}} content {{/vars.container}}
to iterate -
Use
{{{.}}}
for the current element value in iteration -
Use
{{{.key}}}
for thekey
value in current element -
Use
{{{@}}}
for the current element key in iteration
To iterate over a list, for example defined with:
variable_iterator("variable_prefix", "iterator_name", "a,b,c", ",")
Use the following file:
{{#vars.variable_prefix.iterator_name}} {{{.}}} is the current iterator_name value {{/vars.variable_prefix.iterator_name}}
Which will be expanded as:
a is the current iterator_name value b is the current iterator_name value c is the current iterator_name value
To iterate over a container defined by the following json file, loaded
with variable_dict_from_file("variable_prefix", "dict_name", "path")
:
{ "hosts": [ "host1", "host2" ], "files": [ {"name": "file1", "path": "/path1", "users": [ "user1", "user11" ] }, {"name": "file2", "path": "/path2", "users": [ "user2" ] } ], "properties": { "prop1": "value1", "prop2": "value2" } }
Use the following template:
{{#vars.variable_prefix.dict_name.hosts}} {{{.}}} is the current hosts value {{/vars.variable_prefix.dict_name.hosts}} # will display the name and path of the current file {{#vars.variable_prefix.dict_name.files}} {{{.name}}}: {{{.path}}} {{/vars.variable_prefix.dict_name.files}} # will display the users list of each file {{#vars.variable_prefix.dict_name.files}} {{{.name}}}:{{#users}} {{{.}}}{{/users}} {{/vars.variable_prefix.dict_name.files}} # will display the current properties key/value pair {{#vars.variable_prefix.dict_name.properties}} {{{@}}} -> {{{.}}} {{/vars.variable_prefix.dict_name.properties}}
Which will be expanded as:
host1 is the current hosts value host2 is the current hosts value # will display the name and path of the current file file1: /path1 file2: /path2 # will display the users list of each file file1: user1 user11 file2: user2 # will display the current properties key/value pair prop1 -> value1 prop2 -> value2
Note: Starting from CFEngine 3.7, you can use
{{#-top-}} ... {{/-top-}}
to iterate over the top level container.
- source_template: Source file containing a template to be expanded (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
file_from_template_${destination}_{kept, repaired, not_ok, reached}
Build a file from a template
Compatible with nodes running Rudder 4.1 or higher.
These methods write a file based on a provided template and the data available to the agent.
To use these methods (file_from_template_*
), you need to have:
- a template file
- data to fill this template
The template file should be somewhere on the local file system, so if you want to use a file shared from the policy server, you need to copy it first (using file_copy_from_remote_source).
It is common to use a specific folder to store those templates after
copy, for example in ${sys.workdir}/templates/
.
The data that will be used while expanding the template is the data available in the agent at the time of expansion. That means:
-
CFEngine's sytem variables (
${sys.*}
, …) and classes (linux
, ``) - data defined during execution (outcome classes of generic methods, …)
-
classes based on
condition_
generic methods -
data defined in ncf using
variable_*
generic methods, which allow for example to load data from local json or yaml files.
ncf currently supports three templating languages:
- mustache templates, which are documented in file_from_template_mustache
- jinja2 templates, which are documented in file_from_template_jinja2
- CFEngine templates, which are a legacy implementation that is here for compatibility, and should not be used for new templates.
Here is a complete example of templating usage:
The (basic) template file, present on the server in
/PATH_TO_MY_FILE/ntp.conf.mustache
(for syntax reference, see
file_from_template_mustache):
{{#classes.linux}} server {{{vars.configuration.ntp.hostname}}} {{/classes.linux}} {{^classes.linux}} server hardcoded.server.example {{/classes.linux}}
And on your local node in /tmp/ntp.json
, the following json file:
{ "hostname": "my.hostname.example" }
And the following policy:
# Copy the file from the policy server file_copy_from_remote_source("/PATH_TO_MY_FILE/ntp.conf.mustache", "${sys.workdir}/templates/ntp.conf.mustache") # Define the `ntp` varibale in the `configuration` prefix from the json file variable_dict_from_file("configuration", "ntp", "/tmp/ntp.json") # Expand yout template file_from_template_type("${sys.workdir}/templates/ntp.conf.mustache", "/etc/ntp.conf", "mustache") # or # file_from_template_mustache("${sys.workdir}/templates/ntp.conf.mustache", "/etc/ntp.conf")
The destination file will contain the expanded content, for example on a Linux node:
server my.hostname.example
- source_template: Source file containing a template to be expanded (absolute path on the target node)
- destination: Destination file (absolute path on the target node)
- template_type: Template type (cfengine, jinja2 or mustache)
file_from_template_${destination}_{kept, repaired, not_ok, reached}
Remove a file if it exists
Compatible with nodes running Rudder 4.1 or higher.
- target: File to remove (absolute path on the target node)
file_remove_${target}_{kept, repaired, not_ok, reached}
Ensure that a line in a file is replaced by another one
Compatible with nodes running Rudder 4.1 or higher.
You can replace lines in a files, based on regular expression and captured pattern
The content to match in the file is a PCRE regular expression, unanchored that you can replace with the content of replacement.
Content can be captured in regular expression, and be reused with the
notation ${match.1}
(for first matched content), ${match.2}
for
second, etc, and the special captured group ${match.0}
for the whole
text.
Here is an example to remove enclosing specific tags
file_replace_lines("/PATH_TO_MY_FILE/file", "<my>(.*)<pattern>", "my ${match.1} pattern")
- file: File name to edit (absolute path on the target node)
- line: Line to match in the file
- replacement: Line to add in the file as a replacement
file_replace_lines_${file}_{kept, repaired, not_ok, reached}
This is a bundle to expand a template in a specific location
WARNING: This generic method is deprecated. Use file_from_template instead.
Compatible with nodes running Rudder 4.1 or higher.
- tml_file: File name (with full path within the framework) of the template file
- target_file: File name (with full path) where to expand the template
- mode: Mode of destination file
- owner: Owner of destination file
- group: Froup of destination file
file_template_expand_${target_file}_{kept, repaired, not_ok, reached}
Make sure a group is absent
Compatible with nodes running Rudder 4.1 or higher.
- group: Group name
group_absent_${group}_{kept, repaired, not_ok, reached}
Checks status of an HTTP URL
Compatible with nodes running Rudder 4.1 or higher.
Perform a HTTP request on the URL, method and headers provided and check that the response has the expected status code (ie 200, 404, 503, etc)
- method: Method to call the URL (GET, POST, PUT, DELETE)
- url: URL to query
- expected_status: Expected status code of the HTTP response
- headers: Headers to include in the HTTP request (as a string, without ')
http_request_check_status_headers_${url}_{kept, repaired, not_ok, reached}
Make an HTTP request with a specific header
Compatible with nodes running Rudder 4.1 or higher.
Perform a HTTP request on the URL, method and headers provided and send the content provided. Will return an error if the request failed.
- method: Method to call the URL (POST, PUT)
- url: URL to send content to
- content: Content to send
- headers: Headers to include in the HTTP request
http_request_content_headers_${url}_{kept, repaired, not_ok, reached}
Logging output for Rudder reports
Compatible with nodes running Rudder 4.1 or higher.
- message: The common part of the message to display
- old_class_prefix: The prefix of the class for different states (0.x version, empty to force new style logging only)
- origin_class_prefix: The prefix of the class for different states (1.x version)
- args: The arguments used to call the generic method (slist)
logger_rudder_${old_class_prefix}_{kept, repaired, not_ok, reached}
Logging output for Rudder reports. This interface is for compatiblity with older generic methods and techniques, and is replaced by log_rudder.
WARNING: This generic method is deprecated. Use log_rudder instead.
Compatible with nodes running Rudder 4.1 or higher.
- message: The common part of the message to display
- old_class_prefix: The prefix of the class for different states (0.x version, empty to force new style logging only)
logger_rudder_${old_class_prefix}_{kept, repaired, not_ok, reached}
Enforce the absence of a package
Compatible with nodes running Rudder 4.1 or higher.
See package_state for documentation.
- name: Name of the package
- version: Version of the package or "any" for any version (defaults to "any")
- architecture: Architecture of the package, can be an architecture name or "default" (defaults to "default")
- provider: Package provider to use, can be "yum", "apt", "zypper", "zypper_pattern", "slackpkg", "pkg" or "default" for system default package manager (defaults to "default")
package_absent_${name}_{kept, repaired, not_ok, reached}
Verify if a package is installed in any version
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
package_check_installed_${file_name}_{ok, reached, kept}
if the
package is installed, or
package_check_installed_${file_name}_{not_ok, reached, not_kept, failed}
if the package is not installed
- package_name: Name of the package to check
package_check_installed_${package_name}_{kept, repaired, not_ok, reached}
Install or update a package in its latest version available
WARNING: This generic method is deprecated. Use package_present instead.
Compatible with nodes running Rudder 4.1 or higher.
- package_name: Name of the package to install
package_install_${package_name}_{kept, repaired, not_ok, reached}
Install or update a package in a specific version
WARNING: This generic method is deprecated. Use package_present instead.
Compatible with nodes running Rudder 4.1 or higher.
- package_name: Name of the package to install
- package_version: Version of the package to install (can be "latest" to install it in its latest version)
package_install_${package_name}_{kept, repaired, not_ok, reached}
Install a package or verify if it is installed in a specific version, or higher or lower version than a version specified
WARNING: This generic method is deprecated. Use package_present instead.
Compatible with nodes running Rudder 4.1 or higher.
Example:
methods: "any" usebundle => package_install_version_cmp("postgresql", ">=", "9.1", "verify");
- package_name: Name of the package to install or verify
- version_comparator: Comparator between installed version and defined version, can be ==,⇐,>=,<,>,!=
- package_version: The version of the package to verify (can be "latest" for latest version)
- action: Action to perform, can be add, verify (defaults to verify)
package_install_${package_name}_{kept, repaired, not_ok, reached}
Install a package or verify if it is installed in a specific version, or higher or lower version than a version specified, optionally test update or not (Debian-, Red Hat- or SuSE-like systems only)
WARNING: This generic method is deprecated. Use package_present instead.
Compatible with nodes running Rudder 4.1 or higher.
Example:
methods: "any" usebundle => package_install_version_cmp_update("postgresql", ">=", "9.1", "verify", "false");
- package_name: Name of the package to install or verify
- version_comparator: Comparator between installed version and defined version, can be ==,⇐,>=,<,>,!=
- package_version: The version of the package to verify (can be "latest" for latest version)
- action: Action to perform, can be add, verify (defaults to verify)
- update_policy: While verifying packages, check against latest version ("true") or just installed ("false")
package_install_${package_name}_{kept, repaired, not_ok, reached}
Enforce the presence of a package
Compatible with nodes running Rudder 4.1 or higher.
See package_state for documentation.
- name: Name of the package, or path to a local package
- version: Version of the package, can be "latest" for latest version or "any" for any version (defaults to "any")
- architecture: Architecture of the package, can be an architecture name or "default" (defaults to "default")
- provider: Package provider to use, can be "yum", "apt", "zypper", "zypper_pattern", "slackpkg", "pkg" or "default" for system default package manager (defaults to "default")
package_present_${name}_{kept, repaired, not_ok, reached}
Remove a package
WARNING: This generic method is deprecated. Use package_absent instead.
Compatible with nodes running Rudder 4.1 or higher.
Example:
methods: "any" usebundle => package_remove("htop");
- package_name: Name of the package to remove
package_remove_${package_name}_{kept, repaired, not_ok, reached}
Enforce the state of a package
Compatible with nodes running Rudder 4.1 or higher.
These methods manage packages using a package manager on the system.
package_present
and package_absent
use a new package implementation,
different from package_install_*
, package_remove_*
and
package_verify_*
. It should be more reliable, and handle upgrades
better. It is compatible though, and you can call generic methods from
both implementations on the same host. The only drawback is that the
agent will have to maintain double caches for package lists, which may
cause a little unneeded overhead.
If you are using ncf inside Rudder, no specific setup is necessary.
If your are using ncf without Rudder, you need to call the
initialization
bundle before using package methods.
There is only one mandatory parameter, which is the package name to install. When it should be installed from a local package, you need to specify the full path to the package as name.
The version parameter allows specifying a version you want installed. It should be the complete versions string as used by the used package manager. This parameter allows two special values:
- any which is the default value, and is satisfied by any version of the given package
- latest which will ensure, at each run, that the package is at the latest available version.
The last parameter is the provider, which is documented in the next section.
You can use package_state_options to pass options to the underlying package manager (currently only with apt package manager).
This method supports several package managers. You can specify the package manager you want to use or let the method choose the default for the local system.
The package providers include a caching system for package information. The package lists (installed, available and available updates) are only updated when the cache expires, or when an operation is made by the agent on packages.
Note: The implementation of package operations is done in scripts
called modules, which you can find in
${sys.workdir}/modules/packages/
.
This package provider uses apt/dpkg to manage packages on the system. dpkg will be used for all local actions, and apt is only needed to manage update and installation from a repository.
This package provider uses yum/rpm to manage packages on the system. rpm will be used for all local actions, and yum is only needed to manage update and installation from a repository.
It is able to downgrade packages when specifying an older version.
This package provider uses zypper/rpm to manage packages on the system. rpm will be used for all local actions, and zypper is only needed to manage update and installation from a repository.
Note: If the package version you want to install contains an epoch, you
have to specify it in the version in the epoch:version
form, like
reported by zypper info
.
This package provider uses zypper with the -t pattern
option to manage
zypper patterns or meta-packages on the system.
Since a zypper pattern can be named differently than the rpm package
name providing it, please always use the exact pattern name (as listed
in the output of zypper patterns
) when using this provider.
Note: When installing a pattern from a local rpm file, Rudder assumes that the pattern is built following the official zypper documentation.
Older implementations of zypper patterns may not be supported by this module.
This package provider uses Slackware’s installpkg and upgradepkg tools to manage packages on the system
This package provider uses FreeBSD’s pkg to manage packages on the system.
# To install postgresql in version 9.1 for x86_64 atchitecture package_present("postgresql", "9.1", "x86_64", ""); # To ensure postgresql is always in the latest available version package_present("postgresql", "latest", "", ""); # To ensure installing postgresql in any version package_present("postgresql", "", "", ""); # To ensure installing postgresql in any version, forcing the yum provider package_present("postgresql", "", "", "yum"); # To ensure installing postgresql from a local package package_present("/tmp/postgresql-9.1-1.x86_64.rpm", "", "", ""); # To remove postgresql package_absent("postgresql", "", "", "");
See also : package_present, package_absent, package_state_options
- name: Name of the package, or path to a local package if state is present
- version: Version of the package, can be "latest" for latest version or "any" for any version (defaults to "any")
- architecture: Architecture of the package, can be an architecture name or "default" (defaults to "default")
- provider: Package provider to use, can be "yum", "apt", "zypper", "zypper_pattern", "slackpkg", "pkg" or "default" for system default package manager (defaults to "default")
- state: State of the package, can be "present" or "absent" (defaults to "present")
package_state_${name}_{kept, repaired, not_ok, reached}
Enforce the state of a package with options
Compatible with nodes running Rudder 4.1 or higher.
See package_state for documentation.
- name: Name of the package, or path to a local package if state is present
- version: Version of the package, can be "latest" for latest version or "any" for any version (defaults to "any")
- architecture: Architecture of the package, can be an architecture name or "default" (defaults to "default")
- provider: Package provider to use, can be "yum", "apt", "zypper", "zypper_pattern", "slackpkg", "pkg" or "default" for system default package manager (defaults to "default")
- state: State of the package, can be "present" or "absent" (defaults to "present")
- options: Options no pass to the package manager (defaults to empty)
package_state_options_${name}_{kept, repaired, not_ok, reached}
Verify if a package is installed in its latest version available
Compatible with nodes running Rudder 4.1 or higher.
- package_name: Name of the package to verify
package_install_${package_name}_{kept, repaired, not_ok, reached}
Verify if a package is installed in a specific version
Compatible with nodes running Rudder 4.1 or higher.
- package_name: Name of the package to verify
- package_version: Version of the package to verify (can be "latest" for latest version)
package_install_${package_name}_{kept, repaired, not_ok, reached}
Set permissions on a file or directory (non recursively)
Compatible with nodes running Rudder 4.1 or higher.
- path: Path to the file/directory
- mode: Mode to enforce (like "640")
- owner: Owner to enforce (like "root")
- group: Group to enforce (like "wheel")
permissions_${path}_{kept, repaired, not_ok, reached}
Verify if a directory has the right permissions non recursively
Compatible with nodes running Rudder 4.1 or higher.
- path: Path of the directory
- mode: Mode to enforce
- owner: Owner to enforce
- group: Group to enforce
permissions_${path}_{kept, repaired, not_ok, reached}
Verify if a directory has the right permissions recursively
Compatible with nodes running Rudder 4.1 or higher.
- path: Path to the directory
- mode: Mode to enforce
- owner: Owner to enforce
- group: Group to enforce
permissions_${path}_{kept, repaired, not_ok, reached}
Verify if a file or directory has the right permissions recursively
Compatible with nodes running Rudder 4.1 or higher.
- path: Path to the file / directory
- mode: Mode to enforce
- owner: Owner to enforce
- group: Group to enforce
permissions_${path}_{kept, repaired, not_ok, reached}
Ensure that a file or directory is present and has the right mode/owner/group
Compatible with nodes running Rudder 4.1 or higher.
- path: Path to edit
- mode: Mode of the path to edit
- owner: Owner of the path to edit
- group: Group of the path to edit
- type: Type of the path to edit (all/files/directories)
- recursion: Recursion depth to enforce for this path (0, 1, 2, …, inf)
permissions_${path}_{kept, repaired, not_ok, reached}
Trigger a repaired outcome when a job should be run
Compatible with nodes running Rudder 4.1 or higher.
This method compute the expected time for running the job, based on the
parameters and splayed uing system ids, and define a conditions based on
this computation: * schedule_simple_${job_id}_kept
if the job should
not be run now * schedule_simple_${job_id}_repaired
if the job should
be run * schedule_simple_${job_id}_error
if their is an inconsistency
in the method parameters
If you want to run a job, at every hour and half-hour (0:00 and 0:30), with no spread across system, with an agent running with default schedule of 5 minutes, and making sure that the job is run (if the agent couldn’t run it, then at the next agent execution the job should be run), you will call the method with the following parameters:
schedule_simple("job_schedule_id", "5", "0", "0", "0", "0", "0", "30", "0", "0", "catchup")
During each run right after o’clock and half-hour, this method will
define the condition schedule_simple_job_schedule_id_repaired, that you
can use as a condition for a generic method command_execution
- job_id: A string to identify this job
- agent_periodicity: Agent run interval (in minutes)
- max_execution_delay_minutes: On how many minutes you want to spread the job
- max_execution_delay_hours: On how many hours you want to spread the job
- start_on_minutes: At which minute should be the first run
- start_on_hours: At which hour should be the first run
- start_on_day_of_week: At which day of week should be the first run
- periodicity_minutes: Desired job run interval (in minutes)
- periodicity_hours: Desired job run interval (in hours)
- periodicity_days: Desired job run interval (in days)
- mode: "nodups": avoid duplicate runs in the same period / "catchup": avoid duplicates and one or more run have been missed, run once before next period / "stateless": no check is done on past runs
schedule_simple_${job_id}_{kept, repaired, not_ok, reached}
Trigger a repaired outcome when a job should be run (avoid losing a job)
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
schedule_simple_${job_id}_{kept,repaired,not_ok,ok,reached}
* _ok or
_kept for when there is nothing to do * _repaired if the job should run
* _not_ok and _reached have their usual meaning If the agent run is
skipped during the period, method tries to catchup the run on next agent
run. If the agent run is skipped twice,, only one run is catched up. If
the agent is run twice (for example from a manual run), the job is run
only once.
- job_id: A string to identify this job
- agent_periodicity: Agent run interval (in minutes)
- max_execution_delay_minutes: On how many minutes you want to spread the job
- max_execution_delay_hours: On how many hours you want to spread the job
- start_on_minutes: At which minute should be the first run
- start_on_hours: At which hour should be the first run
- start_on_day_of_week: At which day of week should be the first run
- periodicity_minutes: Desired job run interval (in minutes)
- periodicity_hours: Desired job run interval (in hours)
- periodicity_days: Desired job run interval (in days)
schedule_simple_${job_id}_{kept, repaired, not_ok, reached}
Trigger a repaired outcome when a job should be run (avoid running twice)
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
schedule_simple_${job_id}_{kept,repaired,not_ok,ok,reached}
* _ok or
_kept for when there is nothing to do * _repaired if the job should run
* _not_ok and _reached have their usual meaning If the agent is run
twice (for example from a manual run), the jo is run only once. However
if the agent run is skipped during the period, the job is never run.
- job_id: A string to identify this job
- agent_periodicity: Agent run interval (in minutes)
- max_execution_delay_minutes: On how many minutes you want to spread the job
- max_execution_delay_hours: On how many hours you want to spread the job
- start_on_minutes: At which minute should be the first run
- start_on_hours: At which hour should be the first run
- start_on_day_of_week: At which day of week should be the first run
- periodicity_minutes: Desired job run interval (in minutes)
- periodicity_hours: Desired job run interval (in hours)
- periodicity_days: Desired job run interval (in days)
schedule_simple_${job_id}_{kept, repaired, not_ok, reached}
Trigger a repaired outcome when a job should be run (without checks)
Compatible with nodes running Rudder 4.1 or higher.
This bundle will define a class
schedule_simple_${job_id}_{kept,repaired,not_ok,ok,reached}
* _ok or
_kept for when there is nothing to do * _repaired if the job should run
* _not_ok and _reached have their usual meaning No effort is done to
check if a run has already been done for this period or not. If the
agent is run twice, the job will be run twice, and if the agent is not
run, the job will no be run.
- job_id: A string to identify this job
- agent_periodicity: Agent run interval (in minutes)
- max_execution_delay_minutes: On how many minutes you want to spread the job
- max_execution_delay_hours: On how many hours you want to spread the job
- start_on_minutes: At which minute should be the first run
- start_on_hours: At which hour should be the first run
- start_on_day_of_week: At which day of week should be the first run
- periodicity_minutes: Desired job run interval (in minutes)
- periodicity_hours: Desired job run interval (in hours)
- periodicity_days: Desired job run interval (in days)
schedule_simple_${job_id}_{kept, repaired, not_ok, reached}
Trigger an action on a service using the approriate tool
Compatible with nodes running Rudder 4.1 or higher.
The service_*
methods manage the services running on the system.
The name of the service is the name understood by the service manager,
except for the is-active-process
action, where it is the regex to
match against the running processes list.
The action is the name of an action to run on the given service. The following actions can be used:
-
start
-
stop
-
restart
-
reload
(orrefresh
) -
is-active
(orstatus
) -
is-active-process
(in this case, the "service" parameter is the regex to match againt process list) -
enable
-
disable
-
is-enabled
Other actions may also be used, depending on the selected service manager.
These methods will detect the method to use according to the platform.
You can run the methods with an info
verbosity level to see which
service manager will be used for a given action.
![]() | Warning |
---|---|
Due to compatibility issues when mixing calls to systemctl and service/init.d, when an init script exists, we will not use systemctl compatibility layer but directly service/init.d. |
The supported service managers are:
- systemd (any unkown action will be passed directly)
- upstart
- smf (for Solaris)
- service command (for non-boot actions, any unkown action will be passed directly)
- /etc/init.d scripts (for non-boot actions, any unkown action will be passed directly)
- SRC (for AIX) (for non-boot actions)
- chkconfig (for boot actions)
- update-rc.d (for boot actions)
- chitab (for boot actions)
- links in /etc/rcX.d (for boot actions)
- Windows services
# To restart the apache2 service service_action("apache2", "restart"); service_restart("apache2");
- service_name: Name of the service
- action: Action to trigger on the service (start, stop, restart, reload, …)
service_action_${service_name}_{kept, repaired, not_ok, reached}
Check if a service is set to not start at boot using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, etc…)
service_check_disabled_at_boot_${service_name}_{kept, repaired, not_ok, reached}
Check if a service is running using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Process name
service_check_running_${service_name}_{kept, repaired, not_ok, reached}
Check if a service is running using ps
Compatible with nodes running Rudder 4.1 or higher.
- service_regex: Regular expression used to select a process in ps output
service_check_running_${service_regex}_{kept, repaired, not_ok, reached}
Check if a service is set to start at boot using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, etc…)
service_check_started_at_boot_${service_name}_{kept, repaired, not_ok, reached}
Force a service not to be enabled at boot
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, etc…)
service_ensure_disabled_at_boot_${service_name}_{kept, repaired, not_ok, reached}
Ensure that a service is running using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, etc…)
service_ensure_running_${service_name}_{kept, repaired, not_ok, reached}
Ensure that a service is running using the appropriate method, specifying the path of the service in the ps output, or using Windows task manager
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, Windows, etc…)
- service_path: Service with its path, as in the output from ps
service_ensure_running_${service_name}_{kept, repaired, not_ok, reached}
Force a service to be started at boot
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service name (as recognized by systemd, init.d, Windows, SRC, SMF, etc…)
service_ensure_started_at_boot_${service_name}_{kept, repaired, not_ok, reached}
Ensure that a service is stopped using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
- service_name: Service
service_ensure_stopped_${service_name}_{kept, repaired, not_ok, reached}
Reload a service using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
See service_action for documentation.
- service_name: Name of the service
service_reload_${service_name}_{kept, repaired, not_ok, reached}
Restart a service using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
See service_action for documentation.
- service_name: Name of the service
service_restart_${service_name}_{kept, repaired, not_ok, reached}
Restart a service using the appropriate method if the specified class is true, otherwise it is considered as not required and success classes are returned.
WARNING: This generic method is deprecated. Use a condition with service_restart instead.
Compatible with nodes running Rudder 4.1 or higher.
See service_action for documentation.
- service_name: Name of the service
- trigger_class: class(es) which will trigger the restart of Service "(package_service_installed|service_conf_changed)" by example
service_restart_${service_name}_{kept, repaired, not_ok, reached}
Start a service using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
See service_action for documentation.
- service_name: Name of the service
service_start_${service_name}_{kept, repaired, not_ok, reached}
Stop a service using the appropriate method
Compatible with nodes running Rudder 4.1 or higher.
See service_action for documentation.
- service_name: Name of the service
service_stop_${service_name}_{kept, repaired, not_ok, reached}
This method retreives a file shared from another Rudder node
Compatible with nodes running Rudder 4.1 or higher.
This method retreives a file shared from a Rudder node using a unique file identifier.
The file will be downloaded using CFEngine protocol and copied into a new file. The destination path must be the complete absolute path of the destination file.
See sharedfile_to_node for a complete example.
INFO: Please note that this method must be used on an agent that is connected to Rudder relay or server (>=4.1)
- source_uuid: which node to take the file from
- file_id: unique name that was used to identify the file on the sender
- file_path: where to put the file content
sharedfile_from_node_${file_id}_{kept, repaired, not_ok, reached}
This method shares a file with another Rudder node
Compatible with nodes running Rudder 4.1 or higher.
This method shares a file with another Rudder node using a unique file identifier.
Read the Rudder documentation for a high level overview of file sharing between nodes.
The file will be kept on the policy server and transmitted to the destination node’s policy server if it is different. It will be kept on this server for the destination node to download as long as it is not replaced by a new file with the same id or remove by expiration of the TTL.
The node you want to share this file with. The uuid of a node is visible
in the Nodes details (in the Web interface) or by entering
rudder agent info
on the target node.
This is a name that will be used to identify the file in the target node. It should be unique and describe the file content.
The local absolute path of the file to share.
The TTL can be:
- A simple integer, in this case it is assumed to be a number of seconds
- A string including units indications, the possible units are:
- days, day or d
- hours, hour, or h
- minutes, minute, or m
- seconds, second or s
The ttl value can look like 1day 2hours 3minutes 4seconds or can be abbreviated in the form 1d 2h 3m 4s, or without spaces 1d2h3m4s or any combination like 1day2h 3minute 4seconds Any unit can be skipped, but the decreasing order needs to be respected.
This is a name that will be used to identify the file once stored on the server. It should be unique and describe the file content.
We have a node A, with uuid 2bf1afdc-6725-4d3d-96b8-9128d09d353c
which wants to share the /srv/db/application.properties
with node B
with uuid 73570beb-2d4a-43d2-8ffc-f84a6817849c
.
We want this file to stay available for one year for node B on its policy server.
The node B wants to download it into
/opt/application/etc/application.properties
.
They have to agree (i.e. it has to be defined in the policies of both
nodes) on the id of the file, that will be used during the exchange,
here it will be application.properties
.
To share the file, node A will use:
sharedfile_to_node("73570beb-2d4a-43d2-8ffc-f84a6817849c", "application.properties", "/srv/db/application.properties", "356 days")
To download the file, node B will use sharedfile_from_node with:
sharedfile_from_node("2bf1afdc-6725-4d3d-96b8-9128d09d353c", "application.properties", "/opt/application/etc/application.properties")
INFO: Please note that this method must be used on a Rudder agent (>=4.1) that is connected to Rudder relay or server (>=4.1)
- target_uuid: which node to share the file with
- file_id: unique name that will be used to identify the file on the receiver
- file_path: path of the file to share
- ttl: time to keep the file on the policy server in seconds or in human readable form (see long description)
sharedfile_to_node_${file_id}_{kept, repaired, not_ok, reached}
Remove a user
Compatible with nodes running Rudder 4.1 or higher.
This method ensures that a user does not exist on the system.
- login: User login
user_absent_${login}_{kept, repaired, not_ok, reached}
Create a user
Compatible with nodes running Rudder 4.1 or higher.
This method does not create the user’s home directory.
- login: User login
- description: User description
- home: User’s home directory
- group: User’s primary group
- shell: User’s shell
- locked: Is the user locked ? true or false
user_create_${login}_{kept, repaired, not_ok, reached}
Define a variable that contains key,value pairs (a dictionnary)
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name[key]}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- value: The variable content in JSON format
variable_dict_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable that contains key,value pairs (a dictionnary) from a JSON file
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name[key]}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- file_name: The file name with JSON content
variable_dict_from_file_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable resulting of the merge of two other variables
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name[key]}
with each name replaced with the
parameters of this method.
The resulting variable will be the merge of the two parameters, which means it is built by:
- Taking the content of the first variable
- Adding the content of the second variable, and replacing the keys that were already there
It is only a one-level merge, and the value of the first-level key will be completely replaced by the merge.
This method will fail if one of the variables is not defined. See variable_dict_merge_tolerant if you want to allow one of the variables not to be defined.
If you have a prefix.variable1
variable defined by:
{ "key1": "value1", "key2": "value2", "key3": { "keyx": "valuex" } }
And a prefix.variable2
variable defined by:
{ "key1": "different", "key3": "value3", "key4": "value4" }
And that you use:
variablr_dict_merge("prefix", "variable3, "prefix.variable1", "prefix.variable2")
You will get a prefix.variable3
variable containing:
{ "key1": "different", "key2": "value2", "key3": "value3", "key4": "value4" }
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- first_variable: The first variable, which content will be overriden in the resulting variable if necessary (written in the form variable_prefix.variable_name)
- second_variable: The second variable, which content will override the first in the resulting variable if necessary (written in the form variable_prefix.variable_name)
variable_dict_merge_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable resulting of the merge of two other variables, allowing merging undefined variables
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name[key]}
with each name replaced with the
parameters of this method.
See variable_dict_merge for usage documentation. The only difference is that this method will not fail if one of the variables do not exist, and will return the other one. If both are undefined, the method will still fail.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- first_variable: The first variable, which content will be overriden in the resulting variable if necessary (written in the form variable_prefix.variable_name)
- second_variable: The second variable, which content will override the first in the resulting variable if necessary (written in the form variable_prefix.variable_name)
variable_dict_merge_tolerant_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable that will be automatically iterated over
Compatible with nodes running Rudder 4.1 or higher.
The generated variable is a special variable (slist in cfengine speaking) that is automatically iterated over. When you call a generic method with this variable as a parameter, n calls will be made, one for each items of the variable. Note: there is a limit of 10000 items
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- value: The variable content
- separator: Regular expression that is used to split the value into items ( usually: , )
variable_iterator_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable that will be automatically iterated over
Compatible with nodes running Rudder 4.1 or higher.
The generated variable is a special variable (slist in cfengine speaking) that is automatically iterated over. When you call a generic method with this variable as a parameter, n calls will be made, one for each items of the variable. Note: there is a limit of 10000 items Note: empty items are ignored
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- file_name: The path to the file
- separator_regex: Regular expression that is used to split the value into items ( usually: )
- comments_regex: Regular expression that is used to remove comments ( usually: #.*?(?=) )
variable_iterator_from_file_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable from a string parameter
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- value: The variable content
variable_string_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable from another variable name, with a default value if undefined
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- source_variable: The source variable name
- default_value: The default value to use if source_variable is not defined
variable_string_default_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable from a command output
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- command: The command to execute
variable_string_from_command_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable from a file content
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.
- variable_prefix: The prefix of the variable name
- variable_name: The variable to define, the full name will be variable_prefix.variable_name
- file_name: The path of the file
variable_string_from_file_${variable_name}_{kept, repaired, not_ok, reached}
Define a variable from a mathematical expression
Compatible with nodes running Rudder 4.1 or higher.
To use the generated variable, you must use the form
${variable_prefix.variable_name}
with each name replaced with the
parameters of this method.
Be careful that using a global variable can lead to unpredictable content in case of multiple definition, which is implicitly the case when a technique has more than one instance (directive). Please note that only global variables are available within templates.