Generic methods
This section documents all the generic methods available in the Technique Editor.
Audit
audit_from_command
Execute an audit only command and reports depending on exit code
Usage
Execute an audit only command and reports depending on the exit codes given in parameters. If an exit code is not in the list it will lead to an error status. The command is always executed and the report is adapted to work properly in enforce and in audit mode. It is up to you to make sure the command doesn’t modify the system status at all since it is always executed, even in audit mode.
audit_from_osquery
Audit a system property through osquery
Usage
This method uses osquery to fetch information about the system, and compares the value with the given one, using the provided comparator.
Parameters
-
query
is an osquery query returning exactly one result -
comparator
is the comparator to use:='' for equality,
!='' for non-equality, ``~'' for regex comparison -
value
is the expected value, can be a string or a regex depending on the comparator
Setup
This method requires the presence of osquery on the target nodes. It won’t install it automatically. Check the correct way of doing so for your OS.
Building queries
To learn about the possible queries, read the osquery schema for your osquery version.
You can test the queries before using them with the osqueryi
command,
see the example below.
osqueryi "select cpu_logical_cores from system_info;"
You need to provide a query that returns exactly one value. If it’s not the case, the method will fail as it does not know what to check.
Examples
# To check the number of cpus on the machine audit_from_osquery("select cpu_logical_cores from system_info;", "2");
Will report a compliant report if the machine has 3 cores, and a non compliant one if not.
audit_from_powershell_execution
Execute a Powershell command, script or binary (even in audit mode) and parse its output to report a succes or an error.
Usage
Execute either a command, a script or a binary even in audit mode - it supports piping.
It will:
-
report a success if the execution succeeds and the output matches the given regex.
-
report an error otherwise.
Powershell scripts exiting with non-zero return codes will be flagged as failed.
Note: the command will be executed even in Audit mode, it is up to you to make sure it does not impact the system at all.
Note: the regular expression/string to compare to the output are not anchored and are case insensitive.
Examples:
To return success if process explorer
is running, the command
parameter needs to be
Get-Process | ForEach { ${const.dollar}_.ProcessName }
as the output of the command is a toString() on the generated objects,
so you need to extract the relevant data. And the successRegex
needs
to be explorer
.
Command
command_execution
Execute a command
Usage
Execute the Command in shell.
On Unix based agents, the method status will report:
-
a Repaired if the return code is ``0''
-
an Error if the return code is not ``0''
On Windows based agents the command is executed through Powershell and
its &
operator. The method status will report:
-
an Error in Audit mode as the command will not be executed
-
an Error in Enforce mode if the command did throw an exception
-
an Error in Enforce mode if the
LASTEXITCODE
of the execution was not 0. This can happen when calling `.exe' binaries for instance. -
a Repaired in any other cases
Do not use the ``exit'' command on Windows as the shell used is the same than the one running the agent!
Windows examples
# A simple command execution Write-Output "rudder test" | Out-File "C:\test.txt # Another one with a statement, will report a Repaired if the folder exists, # and an error if it does not. { if ( (Test-Path "C:\Program Files\Rudder" -PathType Container)) { "Rudder folder found!" } else { throw "Rudder folder does not exist!" } }
command_execution_as_user
command_execution_once
Execute a command only once on a node
Usage
This method is useful for specific commands that should only be executed once per node.
If you can spot a condition for the command execution by testing the
state of its target, it is better to use the condition_from_command
method to test the state coupled with the command_execution_result
method to run the command if necessary.
In case of reinstallation or factory-reset of the Rudder agent, this method will no longer detect if a command has already been executed.
The method will:
Define the command_execution_once_${command}_kept
condition and do
nothing if a command_execution_once
has already been executed on this
machine with the same Unique id.
Execute the command if it is the first occurrence and: * If the
parameter Until is any
, it will consider the command as executed
on the machine and define either: *
command_execution_once_${command}_repaired
if the return code is in
ok_codes, * command_execution_once_${command}_error
otherwise. * If
the parameter Until is ok and: * If the return code is in the Ok
codes list, define the command_execution_once_${command}_repaired
condition * If the return code is not in Ok codes it define the
command_execution_once_${command}_error
condition and retry at next
agent run.
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 Ok codes list
Parameters
-
command: Command to run
-
ok_codes: List of codes that produce a repaired status separated with commas (ex: 1,2,5). Defaults to 0.
-
until: Try to execute the command until a particular state: `ok', `any' (defaults to `any')
-
unique_id: To identify the action without losing track if the command changes. Defaults to the command if you don’t need it.
command_execution_result
Execute a command and create result conditions depending on its exit code
Usage
Execute a command and create result conditions 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
Condition
condition_from_command
Execute a command and create result conditions depending on its exit code
Usage
This method executes a command, and defines a ${condition}_true
or a
${condition}_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 and a `${condition}_true condition, -
If the exit code is in the
`False codes''
list, this will produce a kept outcome and a `${condition}_false condition, -
If the exit code is not in
True codes'' nor in
False codes'', or if the command can not be found, it will produce an error outcome and and no condition from${condition}
The created condition is global to the agent.
Windows
On Windows nodes, the exit code is taken from the LASTEXITCODE
which
is defined either by:
-
The exit code of a binary execution (when the command a call to an exe)
-
The return code of a Powershell script
Direct Powershell execution will almost always return 0 as
LASTEXITCODE
value, meaning that you have to execute either a binary
or a Powershell script to control the return code.
Example:
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 define a condition based on its execution
result, you can use:
condition_from_command("network_correctly_defined", "/bin/check_network_status", "0,1,2", "18,52")
-
If the command exits with 0, 1 or 2, then it will define the 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 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 or is not found, then it will define the conditions
-
condition_from_command_network_correctly_defined_error
, -
condition_from_command_network_correctly_defined_reached
-
Notes:
-
In audit mode, this method will still execute the command passed in parameter. Which means that you should only pass non system-impacting commands to this method.
-
Rudder will automatically
`canonify'' the given Condition prefix at execution time, which means that all non `[a-zA-Z0-9_]
characters will be replaced by an underscore.
condition_from_expression
Create a new condition
Usage
This method evaluates an expression, and produces a ${condition}_true
or a ${condition}_false
condition depending on the result of the
expression evaluation:
-
This method always result with a success outcome status
-
If the evaluation results in a
`defined'' state, this will define a `${condition}_true
condition, -
If the evaluation results in an
`undefined'' state, this will produce a `${condition}_false
condition.
Calling this method with a condition expression transforms a complex expression into a single condition.
The created condition is global to the agent.
Example
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")
The method will define: * In any case: *
condition_from_expression_backup_time_kept
*
condition_from_expression_backup_time_reached
* And: *
backup_time_true
if the system is a RedHat like system, on Monday, at
2am. * backup_time_false
if the system not a RedHat like system, or
it’s not Monday, or it’s not 2am * no extra condition if the expression
is invalid (cannot be parsed)
condition_from_expression_persistent
Create a new condition that persists across runs
Usage
This method evaluates an expression (=condition combination), and
produces a ${condition}_true
or a ${condition}_false
condition
depending on the result on the expression, which will lasts for the
Duration time:
-
This method always result with a success outcome status
-
If the expression evaluation results in a
`defined'' state, this will define a `${condition}_true
condition, -
If the expression evaluation results in an
`undefined'' state, this will produce a `${condition}_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 the parameter Duration which defines for how long the target condition will be defined (in minutes). Note that there is no way to persist indefinitely.
Example:
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")
The method will define: * In any case: *
condition_from_expression_persistent_backup_time_kept
*
condition_from_expression_persistent_backup_time_reached
* And: *
backup_time_true
if the system is a RedHat like system, on Monday, at
2am, and will persist for Duration minutes, * backup_time_false
if
the system not a RedHat like system, or it’s not Monday, or it’s not 2am
* no extra condition if the expression is invalid (cannot be parsed)
condition_from_string_match
Test the content of a string variable
Usage
Test a string against a regex pattern and create conditions depending on the match result:
-
${condition}_true
condition is defined if the regex matches -
${condition}_false
condition is defined if the regex does not match the string
The regex is singleline, case sensitive, culture invariant and
implicitly enclosed by the start/end of string delimiters ^
and $
.
This method’s reporting status will always be ``success''.
Examples
-name: Define is_matching_true method: condition_from_string_match params: condition: is_matching value: "Some\nmulti\nline\ntext" regex: "Some.*text"
condition_from_variable_existence
Create a condition from the existence of a variable
Usage
This method define a condition: * {condition}_true
if the variable
named from the parameter Variable name is defined *
{condition}_false
if the variable named from the parameter Variable
name is not defined
Also, this method always result with a success outcome status.
condition_from_variable_match
Test the content of a string variable
Usage
Test a string variable content and create conditions depending on its value:
-
If the variable is found and its content matches the given regex:
-
a
${condition}_true
condition, -
and kept outcome status
-
-
If the variable is found but its content does not match the given regex:
-
a
${condition}_false
condition, -
and a kept outcome status
-
-
If the variable can not be found:
-
a
${condition}_false
condition -
and an error outcome status
-
Be careful, we are using variable name not the value. For example if
you want to match the property value `foo'' you will just need
`node.properties[foo]
without ${…}
syntax
/! Regex for unix machine must be PCRE compatible and those for Windows agent must respect the .Net regex format.
-
If you want to test a technique parameter, use the
technique_id
of the technique as variable prefix and the`parameter_name` as variable name.
The method only supports plain string type variables.
condition_once
Create a new condition only once
Usage
This method define a condition named from the parameter Condition when it is called for the first time. Following agent execution will not define the condition.
This allows executing actions only once on a given machine. The created condition is global to the agent.
In case of reinstallation or factory-reset of the Rudder agent, this method will no longer detect if the condition has already been defined.
Example:
If you use:
condition_once("my_condition")
The first agent run will have the condition my_condition
defined,
contrary to subsequent runs for which no condition will be defined.
See also : command_execution_once
Directory
directory_absent
Ensure a directory’s absence
directory_check_exists
Checks if a directory exists
directory_create
Create a directory if it doesn’t exist
WARNING: This generic method is deprecated. Use directory_present instead.
Dsc
dsc_apply
Ensure that all MOF files under MOFFile are applied via DSC.
dsc_built_in_resource
This generic method defines if service should run or be stopped
Parameters
-
tag
parameter is purely informative and has no impact on the resource. -
ResourceName
must be the explicit name of the DSC resource you wish to apply -
ScriptBlock
must be a powershell script in plain text, returning an Hashtable containing the parameters to pass to the resource.
Note that this method can only apply built-in Windows resources. It will not be able to apply an external resource.
Example
If we want to apply a
Registry
resource. The resourceName
used will be Registry
And a potential
ScriptBlock could be:
$HKLM_SOFT="HKEY_LOCAL_MACHINE\SOFTWARE" $Ensure = "Present" $Key = $HKLM_SOFT + "\ExampleKey" $table = @{} $table.Add("Ensure", $Ensure) $table.Add("Key", $Key) $table.Add("ValueName", "RudderTest") $table.Add("ValueData", "TestData") $table
Note that all the ScriptBlock will be readable on the Rudder logs or in the policy files.
dsc_from_configuration
Compile and apply a given DSC configuration defined by a ps1 file
Usage
Compile and apply a given DSC configuration. The DSC configuration must be defined within a .ps1 file, and is expected to be ``self compilable''. A configuration data file (.psd1) containing variables can also be referenced by the ps1 script, by referring to it in the Configuration call.
The method will try to compile the configuration whenever the policies of the nodes are updated of if the previous compilation did not succeed.
All the Rudder variables are usable in your configuration.
Also the current method only allows DSC configurations to be run on the localhost target node, and when using a DSC push setup. Note that it may conflict with already existing DSC configurations not handled by Rudder.
Example 1 - without external data
Here is a configuration named EnsureWebServer.ps1
with simple Windows
feature management:
Configuration EnsureWebServer { Node 'localhost' { # Install the IIS role WindowsFeature IIS { Ensure = 'Present' Name = 'Web-Server' } # Install the ASP .NET 4.5 role WindowsFeature AspNet45 { Ensure = 'Present' Name = 'Web-Asp-Net45' } } } EnsureWebServer
Example 2 with external data
Dsc configurations can be fed with external data, here is an example
using a datafile Data.psd1
containing:
@{ AllNodes = @(); NonNodeData = @{ ConfigFileContents = "Hello World! This file is managed by Rudder" } }
Used to feed the HelloWorld.ps1
Contents key:
Configuration HelloWorld { Import-DscResource -ModuleName 'PSDesiredStateConfiguration' Node 'localhost' { File HelloWorld { DestinationPath = "${RudderBase}\HelloWorld.txt" Ensure = "Present" Contents = $ConfigurationData.NonNodeData.ConfigFileContents } } } HelloWorld -ConfigurationData /path/to/Data.psd1
Please note that the reference to the data file is done inside the configuration file.
Environment
File
file_augeas_commands
Use Augeas binaries to execute augtool commands and options directly on the agent.
Usage
Augeas is a tool that provides an abstraction layer for all the complexities that turn around editing files with regular expressions.
This method defines a rudder variable from the output of a augtool
command. The method has in total 4 parameters:
-
variable_prefix: target variable prefix
-
variable_name: target variable name
-
commands: augtool script to run
-
autoload: boolean to load or not the common augeas lens, default to
true
Augtool provides bunch of other commands and options that you can use in
this generic method such as match
to print the matches for a specific
path expression, span
to print position in input file corresponding to
tree, retrieve
to transform tree into text and save
to save all
pending changes. If Augeas isn’t installed on the agent, it will
produces an error.
This method will execute the commands via augtool
. The particular
thing you may want to do with this method is using it depending on you
needs and in two cases.
With autoload
Augeas will accordingly load all files and lenses before executing the commands you have specified since autoload is active.
file_augeas_commands("label","value","print /files/etc/hosts/*/ipaddr[../canonical="server.rudder.local"]","") # The variable label.value will be defined as such: ${label.value} -> /files/etc/hosts/2/ipaddr = "192.168.2.2"
file_augeas_commands("label","value","ls files/etc/ \n print /files/etc/ssh/sshd_config","true") # Will define the variable label.value with the list of files availables in /etc and already parsable with augeas, # followed by the dump of the sshd_config file, parsed by augeas.
Without autoload
The second case is when you deactivate that option which means that you
are specifying autoload to false
and in this case you have to load
manually your files and lenses in the commands parameter by using the
set
augeas command. Below is a second example where the lens and file
are explicitly set:
file_augeas_commands("label","value","set /augeas/load/Sshd/lens "Sshd.lns \n set /augeas/load/Sshd/incl "/etc/ssh/sshd_config" \n load \n print /augeas/load/Sshd \n print /augeas/load/Sshd \n print /files/etc/ssh/sshd_config","false")
file_augeas_set
Use augeas commands and options to set a node label’s value.
Usage
Augeas is a tool that provides an abstraction layer for all the complexities that turn around editing files with regular expressions. It’s a tree based hierarchy tool, that handles system configuration files where you can securely modify your files and to do so you have to provide the path to the node label’s value.
Augeas uses lenses which are like sort of modules that are in charge of identifying and converting files into tree and back.
This method uses augtool
to force the value of an augeas node’s label.
Actually there are two ways to use this method:
-
Either by providing the augeas path to the node’s label and let lens and file empty. ** this way augeas will load the common files and lens automatically
-
Or by using a given file path and a specific lens. better performances since only one lens is loaded support custom lens, custom paths (for instance to apply the Hosts lens to another file than
/etc/hosts
) -
Either by simply providing an augeas path to the node’s label
Warning: When you don’t specify the file and lens to use, no backup of the file will be made before editing it.
Two uses cases examples:
In the first case, let’s suppose that you want to set the value of the
ip address of the first line in the /etc/hosts
file to 192.168.1.5
,
to do so you need to provide the augeas path and value parameters.
file_augeas_set("/etc/hosts/1/ipaddr", "192.168.1.5", "", "");
The second case is more efficient, and forces the Hosts
lens to parse
the /etc/hosts
file and set the value for the given path node:
file_augeas_set("/etc/hosts/1/ipaddr", "192.168.1.5", "Hosts", "/etc/hosts");
file_block_present
Ensure that a text block is present in a specific location
Usage
Ensure that a text block is present in the target file. If the block is not found, it will be added at the end of the file.
Examples:
Given a file with the following content:
apple pear banana
Applying the method with the block:
pear orange
Will result in the following content:
apple pear banana pear orange
file_block_present_in_section
Ensure that a section contains exactly a text block
Usage
Ensure that a section contains exactly a text block. A section is delimited by a header and a footer. * If the section exists, its content will be replaced if needed * Otherwise it will be created at the end of the file
file_check_FIFO_pipe
Checks if a file exists and is a FIFO/Pipe
file_check_block_device
Checks if a file exists and is a block device
file_check_character_device
Checks if a file exists and is a character device
file_check_exists
Checks if a file exists
file_check_hardlink
Checks if two files are the same (hard links)
Usage
This bundle will define a condition
file_check_hardlink_${path}_{ok, reached, kept}
if the two files
${path}
and ${path_2}
are hard links of each other, or
file_check_hardlink_${path}_{not_ok, reached, not_kept, failed}
if if
the files are not hard links.
file_check_regular
Checks if a file exists and is a regular file
file_check_socket
Checks if a file exists and is a socket
file_check_symlink
Checks if a file exists and is a symlink
file_check_symlinkto
Checks if first file is symlink to second file
Usage
This bundle will define a condition
file_check_symlinkto_${target}_{ok, reached, kept}
if the file
${path}
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.
file_content
Enforce the content of a file
Usage
Enforce the content of a file. The enforce parameter changes the edition method:
-
If enforce is set to true the file content will be forced
-
If enforce is set to false the file content will be forced line by line. Which means that each line managed can not be duplicated and the order will not be guaranteed.
In most cases, the enforce parameter should be set to true. When enforce is set to false, and the managed lines are:
Bob Alice Charly
Will be compliant with the following file contents:
Bob Alice Charly
Charly Bob Alice Charly
Bob Charly Alice
file_copy_from_local_source
Ensure that a file or directory is copied from a local source
WARNING: This generic method is deprecated. Use file_from_local_source instead.
file_copy_from_local_source_recursion
Ensure that a file or directory is copied from a local source
WARNING: This generic method is deprecated. Use file_from_local_source_recursion instead.
file_copy_from_local_source_with_check
Ensure that a file or directory is copied from a local source if a check command succeeds
WARNING: This generic method is deprecated. Use file_from_local_source_with_check instead.
file_copy_from_remote_source
Ensure that a file or directory is copied from a policy server
WARNING: This generic method is deprecated. Use file_from_remote_source instead.
Usage
Note: This method uses the native agent 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 can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_FILE
file_copy_from_remote_source_recursion
Ensure that a file or directory is copied from a policy server
WARNING: This generic method is deprecated. Use file_from_remote_source_recursion instead.
Usage
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 can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_DIRECTORY_OR_FILE
file_create
Create a file if it doesn’t exist
WARNING: This generic method is deprecated. Use file_present instead.
file_create_symlink
Create a symlink at a destination path and pointing to a source target except if a file or directory already exists.
WARNING: This generic method is deprecated. Use file_symlink_present instead.
file_create_symlink_enforce
Create a symlink at a destination path and pointing to a source target. This is also possible to enforce its creation
WARNING: This generic method is deprecated. Use file_symlink_present_option instead.
file_create_symlink_force
Create a symlink at a destination path and pointing to a source target even if a file or directory already exists.
WARNING: This generic method is deprecated. Use file_symlink_present_force instead.
file_download
Download a file if it does not exist, using curl with a fallback on wget
WARNING: This generic method is deprecated. Use file_from_http_server instead.
file_enforce_content
Enforce the content of a file
WARNING: This generic method is deprecated. Use file_content instead.
file_ensure_block_in_section
Ensure that a section contains exactly a text block
WARNING: This generic method is deprecated. Use file_block_present_in_section instead.
file_ensure_block_present
Ensure that a text block is present in a specific location
WARNING: This generic method is deprecated. Use file_block_present instead.
file_ensure_key_value
Ensure that the file contains a pair of ``key separator value''
WARNING: This generic method is deprecated. Use file_key_value_present instead.
Usage
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_ensure_key_value_option
Ensure that the file contains a pair of ``key separator value'', with options on the spacing around the separator
WARNING: This generic method is deprecated. Use file_key_value_present_option instead.
Usage
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.
Parameters
-
path: 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 spacing (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_parameter_in_list
Ensure that one parameter exists in a list of parameters, on one single line, in the right hand side of a key→values line
WARNING: This generic method is deprecated. Use file_key_value_parameter_present_in_list instead.
Usage
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. Optionally, 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
Example
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", " ", "\"", "\"");
Parameters
-
path: 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_not_in_list
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
WARNING: This generic method is deprecated. Use file_key_value_parameter_absent_in_list instead.
Usage
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
Optionally,
you can define leading and closing character to enclose the parameters
Example
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", " ", "\"", "\"");
Parameters
-
path: 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_present_in_ini_section
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.
WARNING: This generic method is deprecated. Use file_key_value_present_in_ini_section instead.
file_ensure_keys_values
Ensure that the file contains all pairs of ``key separator value'', with arbitrary separator between each key and its value
WARNING: This generic method is deprecated. Use file_keys_values_present instead.
Usage
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.
Example
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_ensure_line_present_in_ini_section
Ensure that a line is present in a section in a specific location. The objective of this method is to handle INI-style files.
WARNING: This generic method is deprecated. Use file_line_present_in_ini_section instead.
file_ensure_line_present_in_xml_tag
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.
WARNING: This generic method is deprecated. Use file_line_present_in_xml_tag instead.
file_ensure_lines_absent
Ensure that a line is absent in a specific location
WARNING: This generic method is deprecated. Use file_lines_absent instead.
file_ensure_lines_present
Ensure that one or more lines are present in a file
WARNING: This generic method is deprecated. Use file_lines_present instead.
file_from_http_server
Download a file if it does not exist, using curl with a fallback on wget
Usage
This method finds a HTTP command-line tool and downloads the given source into the destination if it does not exist yet.
This method will NOT update the file after the first download until its removal.
On Linux based nodes it will tries curl
first and fallback with wget
if needed. On Windows based nodes, only curl
will be used.
file_from_local_source
Ensure that a file or directory is copied from a local source
Usage
Ensure that a file or directory is copied from a local source on and from the target node. The copy is not recursive if the target is a directory. To copy recursively a folder from a local source, use the File from local source recursion method.
file_from_local_source_recursion
Ensure that a file or directory is copied from a local source
Usage
Ensure that a file or directory is copied from a local source. If the source is a directory, you can force a maximum level of copy recursion.
-
0 being no recursion, which will only create an empty folder
-
inf being a complete recursive copy of the folder
-
1,2,3,… will force the maximal level of recursion to copy
file_from_local_source_with_check
Ensure that a file or directory is copied from a local source if a check command succeeds
Usage
This method is a conditional 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).
Examples
# To copy a configuration file only if it passes a config test: file_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
file_from_remote_source
Ensure that a file or directory is copied from a policy server
Usage
Note: This method uses the agent native 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 can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_FILE
file_from_remote_source_recursion
Ensure that a file or directory is copied from a policy server
Usage
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 can download a file from the shared files with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_DIRECTORY_OR_FILE
file_from_remote_template
Build a file from a template on the Rudder server
Usage
To use this method, you need to have:
-
a template on the Rudder server shared folder
-
data to fill this template
The template needs to be located in the shared-files folder and can be accessed with:
/var/rudder/configuration-repository/shared-files/PATH_TO_YOUR_FILE
The data that will be used while expanding the template is the data available in the agent at the time of expansion. That means:
-
Agent’s system variables (
${sys.*}
, …) and conditions (linux
, …) -
data defined during execution (result conditions of generic methods, …)
-
conditions based on
condition_
generic methods -
data defined using
variable_*
generic methods, which allow for example to load data from local json or yaml files.
Template types
Supported templating languages:
-
mustache templates, which are documented in file_from_template_mustache
-
jinja2 templates, which are documented in file_from_template_jinja2
Reporting
This method will provide extra log_warning
message if the template was
not updated, but the destination file is modified.
file_from_shared_folder
Ensure that a file or directory is copied from the Rudder shared folder.
Usage
Ensure that a file or directory is copied from the Rudder shared folder.
The Rudder shared folder is located on the Rudder server under
/var/rudder/configuration-repository/shared-files
. Every file/folder
in the shared folder will be available for every managed node. This
method will download and update the destination file from a source taken
from this shared folder. A file in the shared folder will be updated on
the node side at agent run.
file_from_string_mustache
Build a file from a mustache string
Usage
Build a file from a mustache string. Complete mustache documentation is available in the file_from_template_mustache method documentation.
file_from_template
Build a file from a legacy CFEngine template
WARNING: This generic method is deprecated. This method uses CFEngine’s templating which is deprecated and not portable across agents. Please use file_from_template_mustache or file_from_template_jinja2 instead.
Usage
See file_from_template_type for general documentation about templates usage.
file_from_template_jinja2
Build a file from a jinja2 template
Usage
See file_from_template_type for general documentation about templates usage.
This generic method will build a file from a jinja2 template using data (conditions and variables) found in the execution context.
Setup
It requires to have the jinja2 python module installed on the node, it
can usually be done in ncf with
package_present("python-jinja2", "", "", "")
.
If you are using a jinja2 version older than 2.7 trailing newlines will not be preserved in the destination file. |
Syntax
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 conditions -
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/extensions/jinja2_custom.py
For instance, to add a filter to uppercase 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 uppercase(input): return input.upper() def odd(value): return True if (value % 2) else False FILTERS = {'uppercase': uppercase} TESTS = {'odd': odd}
These filters and tests will be usable in your jinja2 templates automatically.
Conditions
To display content based on conditions definition:
{% if classes.my_condition is defined %} display this if defined {% endif %} {% if not classes.my_condition is defined %} display this if not defined {% endif %}
Note: You cannot use condition expressions here.
You can also use other tests, for example other built-in ones or those
defined in jinja2_custom.py
:
{% if vars.variable_prefix.my_number is odd %} display if my_number is odd {% endif %}
Scalar variables
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 | uppercase }}
Will display the variable in uppercase.
Iteration
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
System variables
Some sys
dict variables (like sys.ipv4
) are also accessible as
string, for example:
-
${sys.ipv4}
gives54.32.12.4
-
$[sys.ipv4[ethO]}
gives54.32.12.4
-
$[sys.ipv4[eth1]}
gives10.45.3.2
These variables are not accessible as dict in the templating data, but are represented as string:
-
ipv4
is a string variable in thesys
dict with value54.32.12.4
-
ipv4[ethO]
is a string variable in thesys
dict with value54.32.12.4
-
ipv4
is not accessible as a dict in the template
To access these value, use the following syntax in your jinja2 templates:
vars.sys['ipv4[eth0]']
file_from_template_mustache
Build a file from a mustache template
Usage
See file_from_template_type for general documentation about templates usage.
Syntax
Mustache is a logic-less templating language, available in a lot of languages, and used for file templating in Rudder. The mustache syntax reference is https://mustache.github.io/mustache.5.html. The Windows implementation follows the standard, the Unix one is a bit richer as describe below.
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 conditions -
vars
to access all variables
Classes
Here is how to display content depending on conditions definition:
{{#classes.my_condition}} content when my_condition is defined {{/classes.my_condition}} {{^classes.my_condition}} content when my_condition is *not* defined {{/classes.my_condition}}
Note: You cannot use condition expressions here.
Scalar variable
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
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
{{{.key}}}
for thekey
value in current element (Linux only) -
Use
{{{@}}}
for the current element key in iteration (Linux only)
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}} # Lines below will only be properly rendered in unix Nodes # 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 # Lines below will only be properly rendered in unix Nodes # 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: You can use {{#-top-}} … {{/-top-}}
to iterate over the top
level container.
System variables
Some sys
dict variables (like sys.ipv4
) are also accessible as
string, for example:
-
${sys.ipv4}
gives54.32.12.4
-
$[sys.ipv4[ethO]}
gives54.32.12.4
-
$[sys.ipv4[eth1]}
gives10.45.3.2
These variables are not accessible as dict in the templating data, but are represented as string:
-
ipv4
is a string variable in thesys
dict with value54.32.12.4
-
ipv4[ethO]
is a string variable in thesys
dict with value54.32.12.4
-
ipv4
is not accessible as a dict in the template
To access these value, use the following syntax in your mustache templates:
{{{vars.sys.ipv4[eth0]}}}
file_from_template_type
Build a file from a template
Usage
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}/tmp/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:
-
Agent’s system variables (
${sys.*}
, …) and conditions (linux
, …) -
data defined during execution (result conditions of generic methods, …)
-
conditions 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.
Template types
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.
Example
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}/tmp/templates/ntp.conf.mustache") # Define the `ntp` variable in the `configuration` prefix from the json file variable_dict_from_file("configuration", "ntp", "/tmp/ntp.json") # Expand your template file_from_template_type("${sys.workdir}/tmp/templates/ntp.conf.mustache", "/etc/ntp.conf", "mustache") # or # file_from_template_mustache("${sys.workdir}/tmp/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
file_key_value_parameter_absent_in_list
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
Usage
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 Optionally, you can define leading and closing character to enclose the parameters
Example
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", " ", "\"", "\"");
Parameters
-
path: 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_key_value_parameter_present_in_list
Ensure that one parameter exists in a list of parameters, on one single line, in the right hand side of a key→values line
Usage
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. Optionally, 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
Example
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", " ", "\"", "\"");
Parameters
-
path: 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_key_value_present
Ensure that the file contains a pair of ``key separator value''
Usage
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_key_value_present_in_ini_section
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.
file_key_value_present_option
Ensure that the file contains a pair of ``key separator value'', with options on the spacing around the separator
Usage
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.
Parameters
-
path: 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)
-
option: Option for the spacing around the separator: strict, which prevent spacing (space or tabs) around separators, or lax which accepts any number of spaces around separators
file_keys_values_present
Ensure that the file contains all pairs of ``key separator value'', with arbitrary separator between each key and its value
Usage
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.
Example
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_line_present_in_ini_section
Ensure that a line is present in a section in a specific location. The objective of this method is to handle INI-style files.
file_line_present_in_xml_tag
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.
file_lines_absent
Ensure that a line is absent in a specific location
Usage
Edit the file, and ensure it does not contain the defined line. Regular expression can be used for both the file name and the lines absent.
file_lines_present
Ensure that one or more lines are present in a file
Usage
Edit the file, and ensure it contains the defined line(s). Regular expression can be used for the file name.
file_remove
Remove a file if it exists
WARNING: This generic method is deprecated. Use file_absent instead.
file_replace_lines
Ensure that a line in a file is replaced by another one
Syntax
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.
This regular expression must not match the string used as a
replacement. For example, to set kernel.shmmax=5678
, the regular
expression would be kernel.shmmax=(?!5678$).*
and the string used as
replacement kernel.shmmax=5678
Note that if you want to replace a
key-value line, method File key-value present
is more suited.
Example
Here is an example to remove enclosing specific tags
file_replace_lines("/PATH_TO_MY_FILE/file", "<my>(.*)<pattern>", "my ${match.1} pattern")
file_report_content
Report the content of a file
Usage
Report the content of a file.
This method does nothing on the system, but only reports a complete or partial content from a given file. This allows centralizing this information on the server, and avoid having to connect on each node to get this information.
This method only works in ``Full Compliance'' reporting mode. |
Parameters
Target
This is the file you want to report content from. The method will return an error if it does not exist.
Examples
# To get the whole /etc/hosts content file_report_content("/etc/hosts", "", ""); # To get lines starting by "nameserver" in /etc/resolv.conf file_report_content("/etc/resolv.conf", "^nameserver", ""); # To get lines containing "rudder" from /etc/hosts with 3 lines of context file_report_content("/etc/hosts", "rudder", "3");
file_report_content_head
Report the head of a file
Usage
Report the head of a file.
This method does nothing on the system, but only reports a partial content from a given file. This allows centralizing this information on the server, and avoid having to connect on each node to get this information.
This method only works in ``Full Compliance'' reporting mode. |
file_report_content_tail
Report the tail of a file
Usage
Report the tail of a file.
This method does nothing on the system, but only reports a partial content from a given file. This allows centralizing this information on the server, and avoid having to connect on each node to get this information.
This method only works in ``Full Compliance'' reporting mode. |
Parameters
file_symlink_present
Create a symlink at a destination path and pointing to a source target except if a file or directory already exists.
file_symlink_present_force
Create a symlink at a destination path and pointing to a source target even if a file or directory already exists.
file_symlink_present_option
Create a symlink at a destination path and pointing to a source target. This is also possible to enforce its creation
file_template_expand
This is a bundle to expand a template in a specific location
WARNING: This generic method is deprecated. This method uses CFEngine’s templating which is deprecated and not portable across agents. Please use file_from_template_mustache or file_from_template_jinja2 instead.
Http
http_request_check_status_headers
Checks status of an HTTP URL
Usage
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)
http_request_content_headers
Make an HTTP request with a specific header
Usage
Perform a HTTP request on the URL, method and headers provided and send the content provided. Will return an error if the request failed.
Kernel
kernel_module_configuration
Ensure that the modprobe configuration of a given kernel module is correct
Usage
Ensure that the modprobe configuration of a given kernel module is correct. Rudder will search for the module configuration in a per-module dedicated section in /etc/modprobe.d/managed_by_rudder.conf.
-
If the module configuration is not found or incorrect, Rudder will (re-)create its configuration.
-
If the module is configured but with a different option file than used by Rudder, it will add the expected one in /etc/modprobe.d/managed_by_rudder.conf but will leave intact the already present one.
The configuration syntax must respect the one used by /etc/modprobe.d
defined in the modprobe.d manual page.
# To pass a parameter to a module: options module_name parameter_name=parameter_value # To blacklist a module blacklist modulename # etc…
Notes:
If you want to force the module to be loaded at boot, use instead the
method kernel_module_enabled_at_boot
which uses other Rudder dedicated
files.
Example:
To pass options to a broadcom module * name
= b43 * configuration
=
options b43 nohwcrypt=1 qos=0
Will produce the resulting block in
/etc/modprobe.d/managed_by_rudder.conf:
# b43 start section options b43 nohwcrypt=1 qos=0 # b43 end section
kernel_module_enabled_at_boot
Ensure that a given kernel module will be loaded at system boot
Usage
Ensure that a given kernel module is enabled at boot on the system. This method only works on systemd systems. Rudder will look for a line matching the module name in a given section in the file:
-
/etc/modules-load.d/enabled_by_rudder.conf
on systemd systems
If the module is already enabled by a different option file than used by Rudder, it will add an entry in the file managed by Rudder listed above, and leave intact the already present one. The modifications are persistent and made line per line, meaning that this Generic Method will never remove lines in the configuration file but only add it if needed.
Please note that this method will not load the module nor configure it,
it will only enable its loading at system boot. If you want to force the
module to be loaded, use instead the method kernel_module_loaded
. If
you want to configure the module, use instead the method
kernel_module_configuration
.
kernel_module_loaded
Ensure that a given kernel module is loaded on the system
Monitoring
monitoring_parameter
Add a monitoring parameter to a node (requires a monitoring plugin)
Package
package_absent
Enforce the absence of a package
Usage
See package_state for documentation.
Parameters
-
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'',ips'',
nimclient'',snap'' or
default'' for system default package manager (defaults to ``default'')
package_check_installed
Verify if a package is installed in any version
WARNING: This generic method is deprecated. Use package_present in audit mode instead.
package_install
Install or update a package in its latest version available
WARNING: This generic method is deprecated. Use package_present instead.
package_install_version
Install or update a package in a specific version
WARNING: This generic method is deprecated. Use package_present instead.
package_install_version_cmp
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.
Usage
Example:
methods: "any" usebundle => package_install_version_cmp("postgresql", ">=", "9.1", "verify");
Parameters
-
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_version_cmp_update
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.
Usage
Example:
methods: "any" usebundle => package_install_version_cmp_update("postgresql", ">=", "9.1", "verify", "false");
Parameters
-
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_present
Enforce the presence of a package
Usage
See package_state for documentation.
Parameters
-
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'',ips'',
nimclient'',snap'' or
default'' for system default package manager (defaults to ``default'')
package_remove
Remove a package
WARNING: This generic method is deprecated. Use package_absent instead.
package_state
Enforce the state of a package
Usage
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. These methods will update the
corresponding package if updates are available New updates may not be
detected even if there are some available, this is due to the update
cache that is refresh every 4 hours by default, you can modify this
behaviour called updates_cache_expire
in rudder
global parameter
Package parameters
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 (not supported with snap). 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).
Note: On RPM-based systems, to get the precise version to use in the
version
parameter, you can use the following commands:
sudo rpm --qf "%|EPOCH?{%{epoch}:}:{}|%{version}-%{release}\n" -q PACKAGE_NAME # Examples sudo rpm --qf "%|EPOCH?{%{epoch}:}:{}|%{version}-%{release}\n" -q htop # also works with different versions expressions sudo rpm --qf "%|EPOCH?{%{epoch}:}:{}|%{version}-%{release}\n" -q htop-3.3.0 sudo rpm --qf "%|EPOCH?{%{epoch}:}:{}|%{version}-%{release}\n" -q htop-3.3.0-1.fc39
Package providers
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/
.
apt
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.
rpm
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.
zypper
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
.
zypper_pattern
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 provider doesn’t support installation from a file.
ips
This package provider uses Solaris’s pkg command to manage packages from IPS repositories on the system. This provider doesn’t support installation from a file.
nimclient
This package provider uses AIX’s nim client to manage packages from nim This provider doesn’t support installation from a file.
snap
This package provider uses Ubuntu’s snap to manage packages on the system This provider doesn’t support installation from a file.
Examples
# To install postgresql in version 9.1 for x86_64 architecture 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
Parameters
-
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'',ips'',
nimclient'',snap'' 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_options
Enforce the state of a package with options
Usage
See package_state for documentation.
Parameters
-
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'',ips'',
nimclient'',snap'' 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_windows
This method manage packages using a chocolatey on the system.
Parameters
Required args:
-
PackageName
Name of target package -
Status
can bepresent'' or
absent''
Optional args:
-
Provider
Provider used to installed the package -
Params
Package parameters, passed to the installer -
Version
can beany'',
latest'' or any exact specific version number -
Source
``any'' or any specific arch -
ProviderParams
provider specific options -
AutoUpgrade
default set to false
Providers
choco
The method is a simple transcription of the cchoco
cChocoPaclageInstaller
DSC resource, adapted to Rudder. The DSC module
cchoco
must be installed on your node before trying to use this
method.
You can check the cchoco/chocolatey documentation to get more detailed information on the parameters. WARNING: If some exceptions are thrown about undefined env PATH variable after fresh cchoco lib in rudder, you may need to reboot your machine or notify your system that the env variables have been changed.
Parameters
-
PackageName: Software name to install
-
Status: `present' or `absent', defaults to `present'
-
Provider: default to choco
-
Params: params to pass to the package installation
-
Version: version, default to latest
-
Source: source
-
ProviderParams: provider parameters, default to choco
-
AutoUpgrade: autoUpgrade, default to false
package_verify
Verify if a package is installed in its latest version available
WARNING: This generic method is deprecated. Use package_present in audit mode
package_verify_version
Verify if a package is installed in a specific version
WARNING: This generic method is deprecated. Use package_present in audit mode
Permissions
permissions
Set permissions on a file or directory (non recursively)
permissions_acl_entry
Verify that an ace is present on a file or directory. This method will append the given aces to the current POSIX ACLs of the target.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be a regex with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Recursive
Can be:
-
true
to apply the given aces to folder and sub-folders and files. -
or
false
to apply to the strict match ofPath
If left blank, recursivity will automatically be set to false
User and Group
ACE for user and group can be left blank if they do not need any specification. If fulfill, they must respect the format:
<username|groupname>:<operator><mode>
with:
-
username
being the Linux account name -
groupname
the Linux group name -
Current
owner user
andowner group
can be designed by the character*
The operator can be: * +
to add the given ACE to the current ones. *
-
to remove the given ACE to the current ones. * =
to force the
given ACE to the current ones.
You can define multiple ACEs by separating them with commas.
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:rwx group::r-- mask::rwx other::---
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
user
: *:-x, bob: -
group
: *:+rw -
other
: =r
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rw- user:bob:--- group::rw- mask::rw- other::r--
This method can not remove a given ACE, see here how the user bob ACE is handled.
permissions_dirs
Verify if a directory has the right permissions non recursively
permissions_dirs_recurse
Verify if a directory and its content have the right permissions recursively
WARNING: This generic method is deprecated. Use permissions_dirs_recursive instead.
permissions_dirs_recursive
Verify if a directory and its content have the right permissions recursively
permissions_group_acl_absent
Verify that an ace is absent on a file or directory for a given group. This method will make sure that no ace is present in the POSIX ACL of the target.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be a regex with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx group::r-- group:bob:rwx mask::rwx other::---
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
group
: bob
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx group::r-- mask::r-- other::---
permissions_group_acl_present
Verify that an ace is present on a file or directory for a given group. This method will make sure the given ace is present in the POSIX ACL of the target for the given group.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be a regex with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Recursive
Can be:
-
true
to apply the given aces to folder and sub-folders and files. -
or
false
to apply to the strict match ofPath
If left blank, recursivity will automatically be set to false
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx group::r-- group:bob:rwx mask::rwx other::---
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
group
: bob -
ace
: -rw
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx group::r-- group:bob:--x mask::r-x other::---
permissions_ntfs
Ensure NTFS permissions on a file for a given user.
Usage
Ensure that the correct NTFS permissions are applied on a file for a given user.
Inheritance and propagation flags can also be managed. If left blank, no propagation will be set.
To manage effective propagation or effective access, please disable the inheritance on the file before applying this generic method.
Note: that the Synchronize
permission may not work in some cases. This
is a known bug.
Right validate set:
None, ReadData, ListDirectory, WriteData, CreateFiles, AppendData, CreateDirectories, ReadExtendedAttributes, WriteExtendedAttributes, ExecuteFile, Traverse, DeleteSubdirectoriesAndFiles, ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, TakeOwnership, Synchronize, FullControl
AccessType validate set:
Allow, Deny
PropagationPolicy validate set:
ThisFolderOnly, ThisFolderSubfoldersAndFiles, ThisFolderAndSubfolders, ThisFolderAndFiles, SubfoldersAndFilesOnly, SubfoldersOnly, FilesOnly
permissions_other_acl_present
Verify that the other ace given is present on a file or directory. This method will make sure the given other ace is present in the POSIX ACL of the target for.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be a regex with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:rwx group::r-- mask::rwx other::r-x
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
other ace
: -rw
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:rwx group::r-- mask::rwx other::--x
permissions_posix_acl_entry_parent
Ensure ACL on a file or folder and all its parent folders
Usage
Ensure ACL on a file or folder and all its parent folders.
Force the given ACL on the target path
(supports globbing).
-
If
recursive
is set totrue
, the permissions will be applied to every files and folder under the resolvedpath
input. -
If the
parent_permissions_*
inputs are not empty, they will be applied to every parent folders to the resolvedpath
input, excepting the root folder/
. -
ACL inputs are expected to be comma separated, and to follow this schema:
-
myuser:wx
to force the ACL entry -
myuser:+wx
to edit the ACL without enforcing them all
-
If the path
input resolves to /this/is/my/path/mylogfile
, parent
folders permissions will be applied to:
/this /this/is /this/is/my /this/is/my/path/
Examples:
-name: Allows bob to write in its logfile method: permissions_posix_acl_entry_parent path: /this/is/my/path/mylogfile recursive: false user: "bob:rwx" parent_permissions_user: "bob:rx"
-name: Allows Bob and Alice to write in its logfile method: permissions_posix_acl_entry_parent path: /this/is/my/path/mylogfile recursive: false user: "bob:rwx,alice:+rwx" parent_permissions_user: "bob:rx,alice:rx"
Parameters
-
path: Path of the file or directory
-
recursive: Recursive Should ACLs cleanup be recursive,
true'' or
false'' (defaults to ``false'') -
user: User acls, comma separated, like: bob:+rwx, alice:-w
-
group: Group acls, comma separated, like: wheel:+wx, anon:-rwx
-
other: Other acls, like -x
-
parent_permissions_user: User acls, comma separated, like: bob:+rwx, alice:-w
-
parent_permissions_group: Group acls, comma separated, like: wheel:+wx, anon:-rwx
-
parent_permissions_other: Other acls, like -x
permissions_posix_acls_absent
Ensure that files or directories has no ACLs set
Parameters
Path
Path can be globbing with the following format:
-
-
matches any filename or directory at one level, e.g. _.cf will match all files in one directory that end in .cf but it won’t search across directories. _/*.cf on the other hand will look two levels deep.
-
-
? matches a single letter
-
[a-z] matches any letter from a to z
-
\{x,y,anything} will match x or y or anything.
Example
The method has basically the same effect as setfacl -b <path>
.
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:vagrant:rwx group::r-- mask::rwx other::---
It will remove all ACLs, and only let classic rights, here:
root@server# getfacl myTestFile # file: myTestFile # owner: root # group: root user::rwx group::r-- other::--- root@server# ls -l myTestFile -rwxr----- 1 root root 0 Mar 22 11:24 myTestFile root@server#
permissions_recurse
Verify if a file or directory has the right permissions recursively
WARNING: This generic method is deprecated. Use permissions_recursive instead.
permissions_recursive
Verify if a file or directory has the right permissions recursively
Usage
The method ensures that all files and directories under path
have the
correct owner, group owner and permissions.
This method is in fact a call to the permissions_type_recursion method
with all'' type and
inf'' recursion.
permissions_type_recursion
Ensure that a file or directory is present and has the right mode/owner/group
Usage
The method ensure that all files|directories|files and directories have the correct owner, group owner and permissions.
The parameter type can be either: all'',
files'' or
directories''. The parameter recursion can be either:
0,1,2,3,…. inf'' The level of recursion is the maximum depth of
subfolder that will be managed by the method:
-
0 being the current folder/file
-
1 being the current folder/file and its subfolders
-
..
-
inf being the file or the whole folder tree
permissions_user_acl_absent
Verify that an ace is absent on a file or directory for a given user. This method will make sure that no ace is present in the POSIX ACL of the target.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be a regex with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:rwx group::r-- mask::rwx other::---
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
user
: bob
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx group::r-- mask::r-- other::---
permissions_user_acl_present
Verify that an ace is present on a file or directory for a given user. This method will make sure the given ace is present in the POSIX ACL of the target.
Usage
The permissions_*acl_*
manage the POSIX ACL on files and directories.
Please note that the mask will be automatically recalculated when editing ACLs.
Parameters
Path
Path can be globbing with the following format:
-
matches any filename or directory at one level, e.g.
.cf
will match all files in one directory that end in .cf but it won’t search across directories./.cf
on the other hand will look two levels deep. -
?
matches a single letter -
[a-z]
matches any letter from a to z -
{x,y,anything}
will match x or y or anything.
Recursive
Can be:
-
true
to apply the given aces to folder and sub-folders and files. -
or
false
to apply to the strict match ofPath
If left blank, recursivity will automatically be set to false
Example
Given a file with the following getfacl output:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:rwx group::r-- mask::rwx other::---
Applying this method with the following parameters:
-
path
: /tmp/myTestFile -
recursive
: false -
user
: bob -
ace
: -rw
Will transform the previous ACLs in:
root@server# getfacl /tmp/myTestFile getfacl: Removing leading '/' from absolute path names # file: tmp/myTestFile # owner: root # group: root user::rwx user:bob:--x group::r-- mask::r-x other::---
Powershell
powershell_execution
Execute a Powershell command, script or binary, and parse its output to define success, repair or error status
Usage
Execute either a command, a script or a binary - it supports piping. If the execution succeed, it parses the output as a string. It the output contains the successRegex, it defines a success, else if the output contains the repairRegex, it defines a repair, else it defines an error. successRegex and repairRegex are both optional, but at least one must be defined otherwise the method will always return an error.
Examples:
To return success if process explorer
is running, the command
parameter needs to be
Get-Process | ForEach { ${const.dollar}_.ProcessName }
as the output of the command is a toString() on the generated objects,
so you need to extract the relevant data. And the successRegex
needs
to be explorer
.
Note: the regular expression/string to compare to the output are case insensitive and not anchored.
Note: powershell scripts exiting with a non-zero exit code will always result in an error
Note: the $ need to be escaped, otherwise $_ is evaluated at runtime
Registry
registry_entry_absent
Ensure that a registry entry is absent from the given key.
Usage
Ensure that a registry entry is absent from the given key.
There are two different supported syntaxes to describe a Registry Key:
-
with short drive like
HKLM:\SOFTWARE\myKey
-
with long drive name preceded by
Registry::
likeRegistry::HKEY_LOCAL_MACHINE\SOFTWARE\myKey
Examples
- name: Make sure the Rudder reg does not define the unwantedEntry property method: registry_entry_absent key: "HKLM:\SOFTWARE\Rudder" entry: "unwantedEntry" - name: Make sure the Rudder reg does not define the unwantedEntry property method: registry_entry_absent key: "Registry::HKEY_LOCAL_MACHINE:\SOFTWARE\Rudder" entry: "unwantedEntry"
registry_entry_present
Ensure the value of a registry entry is correct.
Usage
If the key and/or its entry does not exist yet, it will be created.
There are two different supported syntaxes to describe a Registry Key:
-
with short drive like
HKLM:\SOFTWARE\myKey
-
with long drive name preceded by
Registry::
likeRegistry::HKEY_LOCAL_MACHINE\SOFTWARE\myKey
Please, note that Rudder can not create new drive and new ``first-level'' Registry Keys.
Examples
- name: Rudder registry "myEntry" property must be set to 1 method: registry_entry_present key: "HKLM:\SOFTWARE\Rudder" entry: "myEntry" value: "1" registryType: "Dword" - name: Rudder registry "myEntry" property must be set to 1 method: registry_entry_present key: "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Rudder" entry: "myEntry" value: "1" registryType: "Dword"
registry_key_absent
Ensure that a registry key does not exist.
Usage
Remove a Registry Key if it is present on the system.
There are two different supported syntaxes to describe a Registry Key:
-
with short drive like
HKLM:\SOFTWARE\myKey
-
with long drive name preceded by
Registry::
likeRegistry::HKEY_LOCAL_MACHINE\SOFTWARE\myKey
Please, note that Rudder can not remove drives and ``first-level'' Registry Keys.
registry_key_present
Ensure that a Registry Key does exist.
Usage
Create a Registry Key if it does not exist.
There are two different supported syntaxes to describe a Registry Key:
-
with short drive like
HKLM:\SOFTWARE\myKey
-
with long drive name preceded by
Registry::
likeRegistry::HKEY_LOCAL_MACHINE\SOFTWARE\myKey
Please, note that Rudder can not create new drive and new ``first-level'' Registry Keys.
Examples
- name: Make sure the Rudder reg key is defined method: registry_entry_present key: "HKLM:\SOFTWARE\Rudder" #### Parameters * **key**: Registry key (ie, HKLM:\Software\Rudder) #### Classes defined
registry_key_present_${key}_\{kept, repaired, not_ok, reached}
## Report ### report_if_condition Report a Rudder report based on a condition. #### Usage This method will only send a Rudder report: If the **condition** is met, it will report a compliant report, with the following message: `**<report_message>** was correct.` Otherwise, it will report an error, with the following message: `**report_message** was incorrect` This method will never be in a repaired state. #### Parameters * **report_message**: Message subject, will be extended based on the report status * **condition**: Condition to report a success #### Classes defined
report_if_condition_${report_message}_\{kept, repaired, not_ok, reached}
## Rudder ### rudder_inventory_trigger Trigger an inventory on the agent #### Usage Trigger a Rudder inventory. This will not run the inventory immediately but next time the agent runs. #### Parameters * **id**: Id of the reporting for this method (internal identifier, needs to be unique for each use of the method) #### Classes defined
rudder_inventory_trigger_${id}_\{kept, repaired, not_ok, reached}
## Schedule ### schedule_simple Trigger a repaired outcome when a job should be run #### Usage 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 #### Example 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` #### Parameters * **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 #### Classes defined
schedule_simple_${job_id}_\{kept, repaired, not_ok, reached}
### schedule_simple_catchup Trigger a repaired outcome when a job should be run (avoid losing a job) #### Usage This bundle will define a condition `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 caught up. If the agent is run twice (for example from a manual run), the job is run only once. #### Parameters * **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) #### Classes defined
schedule_simple_${job_id}_\{kept, repaired, not_ok, reached}
### schedule_simple_nodups Trigger a repaired outcome when a job should be run (avoid running twice) #### Usage This bundle will define a condition `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. #### Parameters * **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) #### Classes defined
schedule_simple_${job_id}_\{kept, repaired, not_ok, reached}
### schedule_simple_stateless Trigger a repaired outcome when a job should be run (without checks) #### Usage This bundle will define a condition `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. #### Parameters * **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) #### Classes defined
schedule_simple_${job_id}_\{kept, repaired, not_ok, reached}
## Service ### service_action Trigger an action on a service using the appropriate tool #### Usage The `service_*` methods manage the services running on the system. #### Parameters ##### Service name 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. ##### Action The action is the name of an action to run on the given service. The following actions can be used: * `start` * `stop` * `restart` * `reload` (or `refresh`) * `is-active` (or `status`) * `is-active-process` (in this case, the "service" parameter is the regex to match against process list) * `enable` * `disable` * `is-enabled` Other actions may also be used, depending on the selected service manager. #### Implementation 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 unknown action will be passed directly) * upstart * smf (for Solaris) * service command (for non-boot actions, any unknown action will be passed directly) * /etc/init.d scripts (for non-boot actions, any unknown 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 #### Examples
To restart the apache2 service
service_action(apache2'',
restart''); service_restart(``apache2'');
#### Parameters * **name**: Name of the service * **action**: Action to trigger on the service (start, stop, restart, reload, ...) #### Classes defined
service_action_${name}_\{kept, repaired, not_ok, reached}
### service_check_disabled_at_boot Check if a service is set to not start at boot using the appropriate method #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_check_disabled_at_boot_${name}_\{kept, repaired, not_ok, reached}
### service_check_running Check if a service is running using the appropriate method #### Parameters * **name**: Process name #### Classes defined
service_check_running_${name}_\{kept, repaired, not_ok, reached}
### service_check_running_ps Check if a service is running using ps #### Parameters * **name**: Regular expression used to select a process in ps output #### Classes defined
service_check_running_${name}_\{kept, repaired, not_ok, reached}
### service_check_started_at_boot Check if a service is set to start at boot using the appropriate method #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_check_started_at_boot_${name}_\{kept, repaired, not_ok, reached}
### service_disabled Force a service not to be enabled at boot #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_disabled_${name}_\{kept, repaired, not_ok, reached}
### service_enabled Force a service to be started at boot #### Parameters * **name**: Service name (as recognized by systemd, init.d, Windows, SRC, SMF, etc...) #### Classes defined
service_enabled_${name}_\{kept, repaired, not_ok, reached}
### service_ensure_disabled_at_boot Force a service not to be enabled at boot **WARNING**: This generic method is deprecated. Use [service_disabled_at_boot](#_service_disabled_at_boot) instead. #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_ensure_disabled_at_boot_${name}_\{kept, repaired, not_ok, reached}
### service_ensure_running Ensure that a service is running using the appropriate method **WARNING**: This generic method is deprecated. Use [service_started](#_service_started) instead. #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_ensure_running_${name}_\{kept, repaired, not_ok, reached}
### service_ensure_running_path 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 **WARNING**: This generic method is deprecated. Use [service_started_path](#_service_started_path) instead. #### Parameters * **name**: Service name (as recognized by systemd, init.d, Windows, etc...) * **path**: Service with its path, as in the output from 'ps' #### Classes defined
service_ensure_running_${name}_\{kept, repaired, not_ok, reached}
### service_ensure_started_at_boot Force a service to be started at boot **WARNING**: This generic method is deprecated. Use [service_enabled](#_service_enabled) instead. #### Parameters * **name**: Service name (as recognized by systemd, init.d, Windows, SRC, SMF, etc...) #### Classes defined
service_ensure_started_at_boot_${name}_\{kept, repaired, not_ok, reached}
### service_ensure_stopped Ensure that a service is stopped using the appropriate method **WARNING**: This generic method is deprecated. Use [service_stopped](#_service_stopped) instead. #### Parameters * **name**: Service #### Classes defined
service_ensure_stopped_${name}_\{kept, repaired, not_ok, reached}
### service_reload Reload a service using the appropriate method #### Usage See [service_action](#_service_action) for documentation. #### Parameters * **name**: Name of the service #### Classes defined
service_reload_${name}_\{kept, repaired, not_ok, reached}
### service_restart Restart a service using the appropriate method #### Usage See [service_action](#_service_action) for documentation. #### Parameters * **name**: Name of the service #### Classes defined
service_restart_${name}_\{kept, repaired, not_ok, reached}
### service_restart_if 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 [service_restart](#_service_restart) with a condition #### Usage See [service_action](#_service_action) for documentation. #### Parameters * **name**: Name of the service * **expression**: Condition expression which will trigger the restart of Service "(package_service_installed|service_conf_changed)" by example #### Classes defined
service_restart_${name}_\{kept, repaired, not_ok, reached}
### service_start Start a service using the appropriate method **WARNING**: This generic method is deprecated. This is an action that should not be used in the general case. If you really want to call the start method, use [service_action](#_service_action). Otherwise, simply call [service_started](#_service_started) #### Usage See [service_action](#_service_action) for documentation. #### Parameters * **name**: Name of the service #### Classes defined
service_start_${name}_\{kept, repaired, not_ok, reached}
### service_started Ensure that a service is running using the appropriate method #### Parameters * **name**: Service name (as recognized by systemd, init.d, etc...) #### Classes defined
service_started_${name}_\{kept, repaired, not_ok, reached}
### service_started_path 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 #### Parameters * **name**: Service name (as recognized by systemd, init.d, Windows, etc...) * **path**: Service with its path, as in the output from 'ps' #### Classes defined
service_started_${name}_\{kept, repaired, not_ok, reached}
### service_status This generic method defines if service should run or be stopped #### Parameters * **name**: Service name * **status**: Desired state for the user - can be 'Stopped' or 'Running' #### Classes defined
service_status_${name}_\{kept, repaired, not_ok, reached}
### service_stop Stop a service using the appropriate method **WARNING**: This generic method is deprecated. This is an action that should not be used in the general case. If you really want to call the stop method, use [service_action](#_service_action). Otherwise, simply call [service_stopped](#_service_stopped) #### Usage See [service_action](#_service_action) for documentation. #### Parameters * **name**: Name of the service #### Classes defined
service_stop_${name}_\{kept, repaired, not_ok, reached}
### service_stopped Ensure that a service is stopped using the appropriate method #### Parameters * **name**: Service #### Classes defined
service_stopped_${name}_\{kept, repaired, not_ok, reached}
## Sharedfile ### sharedfile_from_node This method retrieves a file shared from another Rudder node #### Usage This method retrieves a file shared from a Rudder node using a unique file identifier. The file will be downloaded using native agent protocol and copied into a new file. The destination path must be the complete absolute path of the destination file. See [sharedfile_to_node](#_sharedfile_to_node) for a complete example. #### Parameters * **remote_node**: 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 #### Classes defined
sharedfile_from_node_${file_id}_\{kept, repaired, not_ok, reached}
### sharedfile_to_node This method shares a file with another Rudder node #### Usage 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](https://docs.rudder.io/reference/current/usage/advanced_configuration_management.html#_share_files_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. #### Parameters This section describes the generic method parameters. #### remote_node 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. ##### file_id 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. ##### file_path The local absolute path of the file to share. ##### ttl 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. ##### file_id 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. #### Example: 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](#_sharedfile_from_node) with:
sharedfile_from_node(2bf1afdc-6725-4d3d-96b8-9128d09d353c'',
application.properties'',
``/opt/application/etc/application.properties'')
#### Parameters * **remote_node**: 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) #### Classes defined
sharedfile_to_node_${file_id}_\{kept, repaired, not_ok, reached}
## Sysctl ### sysctl_value Enforce a value in sysctl (optionally increase or decrease it) #### Usage Enforce a value in sysctl #### Behaviors Checks for the current value defined for the given key If it is not set, this method attempts to set it in the file defined as argument If it is set, and corresponds to the desired value, it will success If it is set, and does not correspond, the value will be set in the file defined, sysctl configuration is reloaded with `sysctl --system` and the resulting value is checked. If it is not taken into account by sysctl because its overridden in another file or its an invalid key, the method returns an error #### Prerequisite This method requires an /etc/sysctl.d folder, and the `sysctl --system` option. It does not support Debian 6 or earlier, CentOS/RHEL 6 or earlier, SLES 11 or earlier, Ubuntu 12_04 or earlier, AIX and Solaris. ##### Parameters `key` : the key to enforce/check `value` : the expected value for the key `filename` : filename (without extension) containing the key=value when need to be set, within /etc/sysctl.d. This method adds the correct extension at the end of the filename Optional parameter: `min`: The value is the minimal value we request. the value is only changed if the current value is lower than `value` `max`: The value is the maximal value we request: the value is only changed if the current value is higher than `value` `default` (default value): The value is strictly enforced. Comparison is numerical if possible, else alphanumerical So 10 > 2, but Test10 < Test2 #### Examples To ensure that swappiness is disabled, and storing the configuration parameter in 99_rudder.conf
sysctl_value(vm.swappiness'',
99_rudder'', ``0'', "")
To ensure that the UDP buffer is at least 26214400
sysctl_value(net.core.rmem_max'',
99_rudder'', 26214400'',
min'')
#### Parameters * **key**: The key to enforce * **value**: The desired value * **filename**: File name where to put the value in /etc/sysctl.d (without the .conf extension) * **option**: Optional modifier on value: Min, Max or Default (default value) #### Classes defined
sysctl_value_${key}_\{kept, repaired, not_ok, reached}
## User ### user_absent Remove a user #### Usage This method ensures that a user does not exist on the system. #### Parameters * **login**: User login #### Classes defined
user_absent_${login}_\{kept, repaired, not_ok, reached}
### user_create Create a user **WARNING**: This generic method is deprecated. Please split into calls to other user_* methods: [user_present](#_user_present) [user_fullname](#_user_fullname) [user_home](#_user_home) [user_primary_group](#_user_primary_group) [user_shell](#_user_shell) and [user_locked](#_user_locked) #### Usage This method does not create the user's home directory. #### Parameters * **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 #### Classes defined
user_create_${login}_\{kept, repaired, not_ok, reached}
### user_fullname Define the fullname of the user, user must already exists. #### Usage This method does not create the user. #### Parameters * **login**: User's login * **fullname**: User's fullname #### Classes defined
user_fullname_${login}_\{kept, repaired, not_ok, reached}
### user_group Define secondary group for a user #### Usage Ensure that a user is within a group #### Behavior Ensure that the user belongs in the given secondary group (non-exclusive) ##### Parameters `login` : the user login `group_name`: secondary group name the user should belong to (non-exclusive) #### Examples To ensure that user `test` belongs in group `dev`
user_group(test'',
dev'')
Note that it will make sure that user test is in group dev, but won't remove it from other groups it may belong to #### Parameters * **login**: User login * **group_name**: Secondary group name for the user #### Classes defined
user_group_${login}_\{kept, repaired, not_ok, reached}
### user_home Define the home of the user. User must already exists. #### Usage This method does not create the user, nor the home directory. entry example: /home/myuser The home given will be set, but not created. #### Parameters * **login**: User's login * **home**: User's home #### Classes defined
user_home_${login}_\{kept, repaired, not_ok, reached}
### user_locked Ensure the user is locked. User must already exist. #### Usage This method does not create the user. Note that locked accounts will be marked with "!" in /etc/shadow, which is equivalent to "*". To unlock a user, apply a user_password method. #### Parameters * **login**: User's login #### Classes defined
user_locked_${login}_\{kept, repaired, not_ok, reached}
### user_password_clear Ensure a user's password. as used in the UNIX /etc/shadow file. #### Usage User must exists, password will appear in clear text in code. An empty password will lead to an error and be notified. #### Parameters * **login**: User login * **password**: User clear password #### Classes defined
user_password_clear_${login}_\{kept, repaired, not_ok, reached}
### user_password_hash Ensure a user's password. Password must respect `$id$salt$hashed` format as used in the UNIX /etc/shadow file. #### Usage User must exists, password must be pre-hashed. Does not handle empty password accounts. See UNIX /etc/shadow format. entry example: `$1$jp5rCMS4$mhvf4utonDubW5M00z0Ow0` An empty password will lead to an error and be notified. #### Parameters * **login**: User login * **password**: User hashed password #### Classes defined
user_password_hash_${login}_\{kept, repaired, not_ok, reached}
### user_present Ensure a user exists on the system. #### Usage This method does not create the user's home directory. Primary group will be created and set with default one, following the useradd default behavior. As in most UNIX system default behavior user creation will fail if a group with the user name already exists. #### Parameters * **login**: User login #### Classes defined
user_present_${login}_\{kept, repaired, not_ok, reached}
### user_primary_group Define the primary group of the user. User must already exist. #### Usage This method does not create the user. #### Parameters * **login**: User's login * **primary_group**: User's primary group #### Classes defined
user_primary_group_${login}_\{kept, repaired, not_ok, reached}
### user_secondary_groups Define secondary groups for a user #### Usage Make sure that a user belong to the listed groups #### Behavior Ensure that the user belongs in the given secondary group, if `force` is set, the user will be force to only be part of the listed `groups`. #### Examples
-name: bob must be in the printers group method: user_secondary_groups params: login: bob groups: printers force: false
-name: jenkins must only be part of jenkins and docker method: user_secondary_groups params: login: jenkins groups: jenkins,docker force: true
#### Parameters * **login**: User login * **groups**: Comma separated secondary groups name * **force**: Remove user from non-listed groups, "true" or "false" (defaults to "false") #### Classes defined
user_secondary_groups_${login}_\{kept, repaired, not_ok, reached}
### user_shell Define the shell of the user. User must already exist. #### Usage This method does not create the user. entry example: /bin/false #### Parameters * **login**: User's login * **shell**: User's shell #### Classes defined
user_shell_${login}_\{kept, repaired, not_ok, reached}
### user_status This generic method defines if user is present or absent #### Parameters * **user**: User name * **status**: Desired state for the user - can be 'Present' or 'Absent' #### Classes defined
user_status_${user}_\{kept, repaired, not_ok, reached}
### user_uid Define the uid of the user. User must already exists, uid must be non-allowed(unique). #### Usage This method does not create the user. #### Parameters * **login**: User's login * **uid**: User's uid #### Classes defined
user_uid_${login}_\{kept, repaired, not_ok, reached}
## Variable ### variable_dict Define a variable that contains key,value pairs (a dictionary) #### Usage To use the generated variable, you must use the form `${prefix.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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **value**: The variable content in JSON format #### Classes defined
variable_dict_${name}_\{kept, repaired, not_ok, reached}
### variable_dict_from_file Define a variable that contains key,value pairs (a dictionary) from a JSON file #### Usage To use the generated variable, you must use the form `${prefix.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. See [variable_dict_from_file_type](#_variable_dict_from_file_type) for complete documentation. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **file_name**: The absolute local file name with JSON content #### Classes defined
variable_dict_from_file_${name}_\{kept, repaired, not_ok, reached}
### variable_dict_from_file_type Define a variable that contains key,value pairs (a dictionary) from a JSON, CSV or YAML file #### Usage To use the generated variable, you must use the form `${prefix.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). This method will load data from various file formats (yaml, json, csv). #### CSV parsing The input file must use CRLF as line delimiter to be readable (as stated in RFC 4180). #### Examples
To read a json file with format auto detection
variable_dict_from_file_type(prefix'',
var'', /tmp/file.json'',
"
); # To force yaml reading on a non file without yaml extension
variable_dict_from_file_type(''prefix,''var
,''/tmp/file``,''YAML");
If `/tmp/file.json` contains:
\{ key1'':
value1'' }
You will be able to access the `value1` value with `${prefix.var[key1]}`. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **file_name**: The file name to load data from * **file_type**: The file type, can be "JSON", "CSV", "YAML" or "auto" for auto detection based on file extension, with a fallback to JSON (default is "auto") #### Classes defined
variable_dict_from_file_type_${name}_\{kept, repaired, not_ok, reached}
### variable_dict_from_osquery Define a variable that contains key,value pairs (a dictionary) from an osquery query #### Usage To use the generated variable, you must use the form `${prefix.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. This method will define a dict variable from the output of an osquery query. The query will be executed at every agent run, and its result will be usable as a standard dict variable. #### Setup This method requires the presence of [osquery](https://osquery.io/) on the target nodes. It won't install it automatically. Check the correct way of doing so for your OS. #### Building queries To learn about the possible queries, read the [osquery schema](https://osquery.io/schema/) for your osquery version. You can test the queries before using them with the `osqueryi` command, see the example below. #### Examples
To get the number of cpus on the machine
variable_dict_from_osquery(prefix'',
var1'', ``select
cpu_logical_cores from system_info;'');
It will produce the dict from the output of:
osqueryi –json ``select cpu_logical_cores from system_info;''
Hence something like:
[ \{cpu_logical_cores'':
8''}]
To access this value, use the `${prefix.var1[0][cpu_logical_cores]}` syntax. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **query**: The query to execute (ending with a semicolon) #### Classes defined
variable_dict_from_osquery_${name}_\{kept, repaired, not_ok, reached}
### variable_dict_merge Define a variable resulting of the merge of two other variables #### Usage To use the generated variable, you must use the form `${prefix.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](#_variable_dict_merge_tolerant) if you want to allow one of the variables not to be defined. ### Usage 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'' }
#### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **first_variable**: The first variable, which content will be overridden in the resulting variable if necessary (written in the form prefix.name) * **second_variable**: The second variable, which content will override the first in the resulting variable if necessary (written in the form prefix.name) #### Classes defined
variable_dict_merge_${name}_\{kept, repaired, not_ok, reached}
### variable_dict_merge_tolerant Define a variable resulting of the merge of two other variables, allowing merging undefined variables #### Usage To use the generated variable, you must use the form `${prefix.name[key]}` with each name replaced with the parameters of this method. See [variable_dict_merge](#_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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **first_variable**: The first variable, which content will be overridden in the resulting variable if necessary (written in the form prefix.name) * **second_variable**: The second variable, which content will override the first in the resulting variable if necessary (written in the form prefix.name) #### Classes defined
variable_dict_merge_tolerant_${name}_\{kept, repaired, not_ok, reached}
### variable_iterator Define a variable that will be automatically iterated over #### Usage The generated variable is a special variable 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 `${prefix.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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **value**: The variable content * **separator**: Regular expression that is used to split the value into items ( usually: , ) #### Classes defined
variable_iterator_${name}_\{kept, repaired, not_ok, reached}
### variable_iterator_from_file Define a variable that will be automatically iterated over #### Usage The generated variable is a special variable 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 `${prefix.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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **file_name**: The path to the file * **separator_regex**: Regular expression that is used to split the value into items ( usually: \n ) * **comments_regex**: Regular expression that is used to remove comments ( usually: \s*#.*?(?=\n) ) #### Classes defined
variable_iterator_from_file_${name}_\{kept, repaired, not_ok, reached}
### variable_string Define a variable from a string parameter #### Usage To use the generated variable, you must use the form `${prefix.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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **value**: The variable content #### Classes defined
variable_string_${name}_\{kept, repaired, not_ok, reached}
### variable_string_default Define a variable from another variable name, with a default value if undefined #### Usage To use the generated variable, you must use the form `${prefix.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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **source_variable**: The source variable name * **default_value**: The default value to use if source_variable is not defined #### Classes defined
variable_string_default_${name}_\{kept, repaired, not_ok, reached}
### variable_string_escaped Define a variable from another string variable and escape regular expression characters in it. #### Usage To use the generated variable, you must use the form `${<name>_escaped}` where <name> is the composed complete name of the variable you want to escape. Please note that the variable you want to escape must be defined before this method evaluation. #### Example: With a variable defined by the generic method `variable_string`, named `my_prefix.my_variable` and valued to:
something like [] that
Passing `my_prefix.my_variable` as `name` parameter to this method will result in a variable named `my_prefix.my_variable_escaped` and valued to:
something like [] that
#### Parameters * **name**: The variable to define, the full name will be prefix.name #### Classes defined
variable_string_escaped_${name}_\{kept, repaired, not_ok, reached}
### variable_string_from_augeas Use Augeas binaries to call Augtool commands and options to get a node label's value. #### Usage Augeas is a tool that provides an abstraction layer for all the complexities that turn around editing files with regular expressions. It's a tree based hierarchy tool, that handle system configuration files where you can securely modify your files. To do so you have to provide the path to the node label's value. This method aims to use `augtool` to extract a specific information from a configuration file into a rudder variable. If Augeas is not installed on the agent, or if it fails to execute, it will produces an error. * **variable prefix**: target variable prefix * **variable name**: target variable name * **path**: augeas node path, use to describe the location of the target information we want to extract * **lens**: augeas lens to use, optional * **file**: absolute file path to target, optional Actually there are two ways you can use this method: * Either by providing the augeas **path** to the node's label and let **lens** and **file** empty. ** this way augeas will load the common files and lens automatically * Or by using a given **file** path and a specific **lens**. ** better performances since only one lens is loaded ** support custom lens, support custom paths This mechanism is the same as in the `file_augeas_set` method. #### With autoload Let's consider that you want to obtain the value of the ip address of the first line in the `/etc/hosts`: (Note that the `label` and `value` parameters mentioned are naming examples of **variable prefix** and **variable name**, the augeas **path** `/etc/hosts/1/ipaddr` represents the `ipaddr` node label's value (in the augeas mean) in the first line of the file `/etc/hosts`).
variable_string_from_augeas(label'',
value'',/etc/hosts/1/ipaddr'',
"
,''");
#### Without autoload Here we want the same information as in the first example, but we will force the lens to avoid loading unnecessary files.
variable_string_from_augeas(label'',
value'',/etc/hosts/1/ipaddr'',
Hosts'',``/etc/hosts'');
#### Difference with `file augeas command` This method is very similar to the `file augeas command` one, both execute an `augtool` command an dump its output in a rudder variable. But their goal is really different: * This one will parse the output of the augeas `print` that we want to make it directly usable, but will be less flexible in its input. * The `file augeas command` offers much more possibilities to execute an augeas command to modify a file, but the output will be unparsed and most likely unusable as a rudder variable, expect to dump an error or configuration somewhere. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **path**: The path to the file and node label * **lens**: The lens specified by the user in case they want to load a specified lens associated with its file * **file**: The absolute path to the file specified by the user in case they want to load a specified file associated with its lens #### Classes defined
variable_string_from_augeas_${name}_\{kept, repaired, not_ok, reached}
### variable_string_from_command Define a variable from a command output #### Usage Define a variable from a command output. The method will execute a shell command and define a variable `${prefix.name}` from it. * Only `stdout` is kept * The variable will only be defined if the exit code of the command is 0 * If the variable definition is successful, the method will report a success, it will report an error otherwise. * The command will be executed even in *Audit mode* #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **command**: The command to execute #### Classes defined
variable_string_from_command_${name}_\{kept, repaired, not_ok, reached}
### variable_string_from_file Define a variable from a file content #### Usage 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. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be variable_prefix.variable_name * **file_name**: The path of the file #### Classes defined
variable_string_from_file_${name}_\{kept, repaired, not_ok, reached}
### variable_string_from_math_expression Define a variable from a mathematical expression #### Usage To use the generated variable, you must use the form `${prefix.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. #### Usage This function will evaluate a mathematical expression that may contain variables and format the result according to the provided format string. The formatting string uses the standard POSIX printf format. #### Supported mathematical expressions All the mathematical computations are done using floats. The supported infix mathematical syntax, in order of precedence, is: - `(` and `)` parentheses for grouping expressions - `^` operator for exponentiation - `*` and `/` operators for multiplication and division - `%` operators for modulo operation - `+` and `-` operators for addition and subtraction - `==` "close enough" operator to tell if two expressions evaluate to the same number, with a tiny margin to tolerate floating point errors. It returns 1 or 0. - `>=` "greater or close enough" operator with a tiny margin to tolerate floating point errors. It returns 1 or 0. - `>` "greater than" operator. It returns 1 or 0. - `<=` "less than or close enough" operator with a tiny margin to tolerate floating point errors. It returns 1 or 0. - `<` "less than" operator. It returns 1 or 0. The numbers can be in any format acceptable to the C `scanf` function with the `%lf` format specifier, followed by the `k`, `m`, `g`, `t`, or `p` SI units. So e.g. `-100` and `2.34m` are valid numbers. In addition, the following constants are recognized: - `e`: 2.7182818284590452354 - `log2e`: 1.4426950408889634074 - `log10e`: 0.43429448190325182765 - `ln2`: 0.69314718055994530942 - `ln10`: 2.30258509299404568402 - `pi`: 3.14159265358979323846 - `pi_2`: 1.57079632679489661923 (pi over 2) - `pi_4`: 0.78539816339744830962 (pi over 4) - `1_pi`: 0.31830988618379067154 (1 over pi) - `2_pi`: 0.63661977236758134308 (2 over pi) - `2_sqrtpi`: 1.12837916709551257390 (2 over square root of pi) - `sqrt2`: 1.41421356237309504880 (square root of 2) - `sqrt1_2`: 0.70710678118654752440 (square root of 1/2) The following functions can be used, with parentheses: - `ceil` and `floor`: the next highest or the previous highest integer - `log10`, `log2`, `log` - `sqrt` - `sin`, `cos`, `tan`, `asin`, `acos`, `atan` - `abs`: absolute value - `step`: 0 if the argument is negative, 1 otherwise #### Formatting options The format field supports the following specifiers: * `%d` for decimal integer * `%x` for hexadecimal integer * `%o` for octal integer * `%f` for decimal floating point You can use usual flags, width and precision syntax. #### Examples If you use:
variable_string(prefix'',
var'', 10'');
variable_string_from_math_expression(
prefix'', sum'',
2.0+3.0'',
%d''); variable_string_from_math_expression(
prefix'', product'',
"3*$\{prefix.var}
,''%d");
The `prefix.sum` string variable will contain `5` and `prefix.product` will contain `30`. #### Parameters * **prefix**: The prefix of the variable name * **name**: The variable to define, the full name will be prefix.name * **expression**: The mathematical expression to evaluate * **format**: The format string to use #### Classes defined
variable_string_from_math_expression_${name}_\{kept, repaired, not_ok, reached}
### variable_string_match Test the content of a string variable #### Usage Test a variable content and report a success if it matched, or an error if it does not or if the variable could not be found. Regex must respect PCRE format. Please note that this method is designed to only audit a variable state. If you want to use conditions resulting from this generic method, is it recommended to use instead condition_from_variable_match which is designed for it. #### Parameters * **name**: Complete name of the variable being tested, like my_prefix.my_variable * **expected_match**: Regex to use to test if the variable content is compliant #### Classes defined
variable_string_match_${name}_\{kept, repaired, not_ok, reached}
## Windows ### windows_component_absent Ensure that a specific windows component is absent from the system. #### Usage Ensure that a specific windows component is absent from the system. #### Parameters * **component**: Windows component name #### Classes defined
windows_component_absent_${component}_\{kept, repaired, not_ok, reached}
### windows_component_present Ensure that a specific windows component is present on the system. #### Usage Ensure that a specific windows component is present on the system. #### Parameters * **component**: Windows component name #### Classes defined
windows_component_present_${component}_\{kept, repaired, not_ok, reached}
### windows_hotfix_absent Ensure that a specific windows hotfix is absent from the system. #### Usage Ensure that a specific windows hotfix is absent from the system. #### Parameters * **hotfix**: Windows hotfix name (ex: KB4033369) #### Classes defined
windows_hotfix_absent_${hotfix}_\{kept, repaired, not_ok, reached}
### windows_hotfix_present Ensure that a specific windows hotfix is present from the system. #### Usage Ensure that a specific windows hotfix is present from the system. #### Parameters * **hotfix**: Windows hotfix name (ex: KB4033369) * **package_path**: Windows hotfix package absolute path, can be a .msu archive or a .cab file #### Classes defined
windows_hotfix_present_${hotfix}_\{kept, repaired, not_ok, reached}
:leveloffset!:
← Security considerations Generic methods guidelines →