Version information
This version is compatible with:
- Puppet Enterprise 2023.8.x, 2023.7.x, 2023.6.x, 2023.5.x, 2023.4.x, 2023.3.x, 2023.2.x, 2023.1.x, 2023.0.x, 2021.7.x, 2021.6.x, 2021.5.x, 2021.4.x, 2021.3.x, 2021.2.x, 2021.1.x, 2021.0.x, 2019.8.x, 2019.7.x, 2019.5.x, 2019.4.x, 2019.3.x, 2019.2.x, 2019.1.x, 2019.0.x, 2018.1.x, 2017.3.x
- Puppet >= 5.0.0
Start using this module
Add this module to your Puppetfile:
mod 'ripienaar-classifier', '0.1.1'
Learn more about managing modules with a PuppetfileDocumentation
What?
An attempt to port and expand https://github.com/binford2k/puppet-classifier to pure Puppet 4 DSL.
This is a node classifier where you can write classification rules that perform boolean matches on fact data and should a rule match some classes will be included. Any number of classification rules can match on a given node and they can all contribute classes.
Different data tiers can contribute rules and it has a way to just add classes statically like
the old hiera_include()
approach.
NOTE: I'm using semver and as this is still less than 1.0.0 expect breaking changes to happen.
Sample Data
Sticking this in Hiera will create a classification that on RedHat VMs will include the classes centos::vm
and on the node node.example.net
it will also include ntp
in addition.
# common.yaml
classifier::extra_classes:
- sensu
classifier::rules:
RedHat VMs:
match: all
rules:
- fact: "%{facts.os.family}"
operator: ==
value: RedHat
- fact: "%{facts.is_virtual}"
operator: ==
value: "true"
data:
redhat_vm: true
classes:
- centos::vm
# node.example.net.yaml
# remove sensu and install nagios instead, also add extra stuff
classifier::extra_classes:
- --sensu
- nagios
# clients/acme.yaml
# adjust the RedHat VMs rule to add ntp on node
# these machines but also to remove centos::vm and
# install centos::core instead
classifier::rules:
RedHat VMs:
data:
client_redhat: true
classes:
- ntp
- --centos::vm
- centos::core
# add acme client team
classifier::extra_classes:
- acme::sysadmins
node default {
include classifier
}
The extra_classes
parameter lets you specify a array of additional classes without having to construct
rules and they are setup with a knockout of --
so that you can remove lower down results.
At present you can't knockout classes included by rules using a knockout prefix on extra_classes
, this
os something that's planned
You can have many classification rules and which ever match can contribute classes to add
Other classes can access detail about the classification result:
- $classifier::classification - a array of Hashes with matching Rule names and classes
- $classifier::classification_classes - just the classes extracted from the classification
- $classifier::extra_classes - the extra classes resolved from hiera
- $classifier::classes - the list of classes that will be included
- $classifier::data[...] - hash of all the data created by the tiers
- $classifier::enc_used - boolean indicating if the ENC was used
- $classifier::enc_source - path to the data file that was matched and supplied the environment, undef when not used
- $classifier::enc_environment - the environment the ENC set, undef when not used
Reference
The full type description of a rule is:
Hash[String,
Struct[{
match => Optional[Enum["all", "any"]],
rules => Array[
Struct[{
fact => Optional[Data],
operator => Enum["==", "=~", ">", " =>", "<", "<=", "in", "has_ip_network", "has_mac", "has_ip_address", "has_ip_netmask"],
value => Data,
invert => Optional[Boolean]
}]
],
data => Optional[Hash[Pattern[/\A[a-z0-9_][a-zA-Z0-9_]*\Z/], Data]],
classes => Optional[Array[Pattern[/\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\Z/]]]
}]
] $rules = {},
A number of custom types are defined for things like the list of valid operators, valid variable and class names, matches, individual rule and the whole classification. Should you wish to build additional classes that consume data from this tool please validate the input using them
- Classifier::Classification - a single classification made up of rules, classes, data and match type
- Classifier::Classifications - a collection of classifications
- Classifier::Matches - the list of valid match types
- Classifier::Rule - a single rule inside a classification
- Classifier::Data - valid data items
- Classifier::Operators - valid operators
- Classifier::Node - classification result for a node
A few notes:
match
Match can be either any
or all
and it means that in the case where you have many rules
they must either all match a node or at least one.
fact
Use Hiera interprolation to put any fact or trusted data into the rule set. Take note in hiera
to interpolate data you have to quote things like this "${facts.thing}"
which coherse the data
into a string. In the example rule above a boolean fact is cohersed to a string in this manner
and so the match value has to be "true"
as well.
The fact is optional, since some times like in the case of has_ip_network
for example it does
not make sense since it checks a range of facts from the node.
operator
Valid operators are "==", "=~", ">", " =>", "<", "<=", "in", "has_ip_network"
, "has_mac", "has_ip_address",
most of these comparisons are done using the versioncmp
function so you should probably understand it
to really grasp what these will do.
There are a special ones planned like the current has_ip_network
, when using that the fact
is
optional, so something like:
Development Servers:
rules:
- operator: has_ip_network
value: 192.168.88.0
classes:
- development
invert
This inverts the match so setting it true just swaps the whole comparison around, so there is no
!=
operator for example, but you can achieve that using the ==
one and inverting it
data
This is an optional hash of data items kind of like facts, these are accessible in a hash calledcw
$classification::data[..]
after classification
Setting The Environment?
You can set the environment of a node with the help of a ENC included in bin, see ENC.md
Future Plans?
I want to expand the rules so you can use other functions to do evaluation, things like checking if
a node IP belongs to a certain subnet for example, this could be done by adding functions to the
classifier and them into the classifier::evaluate_rule
function as operators perhaps.
At the moment there is has_ip_network
, I am not really sure if this is a good fit so that's experimental
while I figure it out. It might be nice to support any function call there not just ones that's hardcoded
in classifier::evaluate_rule
in order to make the classifier user extendible at their site using any
functions they might have. If we only supported a bunch of hard coded ones I can imaginet his becoming a
huge nightmare to support in the long term as users might want to add many such matchers. A more extendible
approach makes more sense.
But down that road lies basically doing eval()
in puppet and this is just a terrible terrible idea
so I am not sure what's best. It would be very easy to write a function dispatch for any function
that exists, but really it would not be a good idea.
Contact?
R.I.Pienaar / rip@devco.net / http://www.devco.net/ / @ripienaar
# 0.1.1
- Improve handling of nodes with nics that do not have both IPv4 and IPv6
0.1.0
- Remove the old experimental hiera backend to improve compatibility with modern puppet (
- Requires Puppet 5
0.0.11
- Reverse the logic for the
in
expression to be more natural
0.0.10
- Fix a syntax bug in 0.0.8 (Matteo Cerutti @m4ce)
- Perform a deep merge on the calculated data (Matteo Cerutti @m4ce)
0.0.9
- Add has_mac, has_ip_address and has_ip_netmask rule operators
- Add in rule operator (Matteo Cerutti @m4ce)
0.0.8
- Fix loading issues on recent puppet versions
0.0.7
- Add an ENC to facilitate setting the environment
- Support checking if the ENC classification was correctly applied
- Log details about classification results when ENC is in use
0.0.6
- Add the function
classifier::has_network_details
replacing the need for stdlib and old style facts - Fix debug logging of the classification rules before evaluation
0.0.5
- Add
has_ip_network
operator and add stdlib dependency - Remove
unpack_arrays
from the merge options as this function is being removed from Puppet - Fix bug where the classifications were not shown when debug is set
- The
classes
key on a classification is now optional to allow for just exporting data in a rule - The
fact
key on a classification rule is now optional to allow for functions likehas_ip_network
where the left is pointless
0.0.4
- Use Puppet 4.4.0 type aliases to improve readability and validate data at more places
- Since Puppet 4.4.0 now supports deep interpolation of variables from hiera, remove restriction on facts being a fact only
0.0.3
- Add a concept of arbitrary key value pairs on rules which are exposed as
$classification::data
post classification. Setdata
in the rules. - Add a Environment Data Provider that expose the above data to hiera
Dependencies
- puppetlabs/stdlib (>= 4.11.0 < 7.0.0)