Skip to content

Instantly share code, notes, and snippets.

@fanf
Last active August 29, 2015 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fanf/83ade79362bf51c44465 to your computer and use it in GitHub Desktop.
Save fanf/83ade79362bf51c44465 to your computer and use it in GitHub Desktop.
Some example of ncf generic methods for Rudder
#####################################################################################
# Copyright 2015 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################
# @name Demo file content
# @description Report the first 4ko content of a file
#
# @parameter file_name File name
#
# @class_prefix demo_file_content
# @class_parameter file_name
#
# This bundle will define a class demo_file_content_${file_name}_{ok, reached, kept} if the
# file exists, or file_check_exists_${file_name}_{na} if
# the file doesn't exists
bundle agent demo_file_content(file_name)
{
vars:
"class_prefix" string => canonify("demo_file_content_${file_name}");
"file_content" string => readfile( "${file_name}" , "0" );
classes:
"file_exists" expression => fileexists("${file_name}");
methods:
file_exists::
"file_exists"
usebundle => _classes_success("${class_prefix}");
file_exists::
"report"
usebundle => _logger("Content of file ${file_name}: ${file_content}", "${class_prefix}");
!file_exists::
"file_dont_exists"
usebundle => _classes_failure("${class_prefix}");
!file_exists::
"report"
usebundle => _logger("File ${file_name} does not exists", "${class_prefix}");
}
#####################################################################################
# Copyright 2014 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################
# @name File ensure keys -> values from a json are present
# @description Ensure that the file contains all pairs from the json (only one level deep), with arbitrary separator between each key and its value
#
# @parameter file File name to edit
#¬@parameter data A json of "key":"value" to check, for example: '{"k1":"val1", "k2":"val2"}'
#¬@parameter separator Separator between key and value (for example "=" or " ")
#
# @class_prefix file_ensure_keys_values_from_json
# @class_parameter file
#
# This bundle will define a class file_ensure_keys_values_from_json_${file}_{kept,repaired,not_ok,ok,reached}
bundle agent file_ensure_keys_values_from_json(file, data, separator)
{
vars:
"class_prefix" string => canonify("file_ensure_keys_values_from_json_${file}");
"keyvalues" data => parsejson(${data});
files:
"${file}"
create => "true",
edit_line => maintain_key_values("file_ensure_keys_values_from_json.keyvalues", "${separator}"),
edit_defaults => no_backup,
classes => classes_generic("${class_prefix}");
methods:
"report"
usebundle => _logger("Ensure lines in format key${separator}values into ${file}", "${class_prefix}");
}
# Copyright 2014 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################
# @name File ensure attribute in XML node
# @description This is a method that ensure that an attribute is present in a node identified with it's XPath. Need xmlstarlet
#
#
# @parameter file File name to edit
# @parameter xpath XPath that identifies the XML tag to edit
#¬@parameter attrName name of the attribute to check value
# @parameter attrValue value of the attribute to check
#
# @class_prefix file_ensure_line_xml_attribute
# @class_parameter xpath
#
# This bundle will define a class file_ensure_line_xml_attribute_${file}_{kept,repaired,failed,ok,not_ok,reached}
#
# WARNING: this method won't work if xmlstarlet is not installed, and the method should
# at least check for the presence and report an error if the prog is not installed.
# *** This is let as an exercices for the reader. ***
#
bundle agent file_ensure_line_xml_attribute(file, xpath, value)
{
vars:
"class_prefix" string => canonify("file_ensure_line_xml_attribute_${xpath}");
methods:
"cmd"
usebundle => _file_ensure_line_xml_attribute_cmd(${file}, ${xpath}, ${value}, ${class_prefix});
"report"
usebundle => _logger("Check attribute ${xpath} = ${value} into ${file}", "${class_prefix}");
}
bundle agent _file_ensure_line_xml_attribute_cmd(file, xpath, value, class_prefix)
{
commands:
"/usr/bin/xmlstarlet ed --inplace -u \"${xpath}\" -v \"${value}\" ${file}"
contain => in_shell,
classes => classes_generic_success("${class_prefix}");
}
#####################################################################################
# Copyright 2015 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################
# @name IF Command
# @description Define a condition dependand of a command result. This allows to define tests that are
# good citizen regarding reports and are stable even if the command change.
#
# @parameter condition_name The condition name that will be used in classes - must be unique among all technique !
# @parameter command_name the command to execute
#
# @class_prefix if_command
# @class_parameter condition_name
# This bundle will define a class command_execution_${command_name}_{kept,repaired,not_ok,ok,reached}
#
# This bundle is "just" a command execution that don't do any rudder reporting
#
bundle agent if_command(condition_name, command_name)
{
vars:
"class_prefix" string => canonify("if_command_${condition_name}");
methods:
"report"
usebundle => _logger("Condition [${condition_name}] based on the command ${command_name} result", "${class_prefix}"),
ifvarclass => "${class_prefix}_reached";
commands:
"${command_name}"
contain => in_shell,
classes => classes_generic_success("${class_prefix}");
}
body classes classes_generic_success(x)
# Define x prefixed/suffixed with promise outcome
{
promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" };
repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" };
repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" };
repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" };
promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" };
kept_returncodes => { "0" };
repaired_returncodes => { "1","2","3" };
failed_returncodes => { "9999" };
}
@fanf
Copy link
Author

fanf commented Aug 25, 2015

This are common example for ncf generic methods:

  • if_command allows to simply add check in technique based on the result of a command
  • file_ensure_keys_values_from_json.cf allows to define key/values from a json parameter, much better to use it in an UI (go define a CFEngine Array in the technique editor...)
  • file_ensure_line_xml_attribute.cf is an example about how to rely on an external programm to edit XML file. The method is at most a draft, it should AT LEAST check for the presence of xmlstarlet
  • demo_file_content.cf is a hack that send in report the content of file. Can be handy to look in a config file, but really, it's just a hack and better view as an example about how to build new generic methods.

How to add these methods to your Rudder ?

Simply copy the files in /var/rudder/configuration-repository/ncf/30_generic_methods and reload the page of the technique editor: they are available.
It is best for you if you also add the files in the configuration-repository's git and commit them, because, you know, source control, best practices, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment