Animal
Animal is a work-in-progress toward developing a flexible, modular, and powerful rule-based Puppet ENC written in Ruby.
Installation
Add this line to your application's Gemfile:
gem 'animal'
And then execute:
$ bundle
Or install it yourself as:
$ gem install animal
Usage
Rules
Rule Statement Syntax
Animal uses a rules-based approach to classifying nodes, and its rules engine supports a simple yet powerful syntax for building conditions based on installed plugins. It utilizes a delayed merging approach for building a list of Puppet classes to apply to a node, meaning that subtracting a class from a list of classes happens after all the add operations are complete, allowing a subtract to be performed at any point in the rules system. The benefit is that rules need not be evaluated in any particular order.
The actual syntax should be familiar enough for people used to writing either SQL or Puppet code. Here is an example of a simple rule statement:
Fact["certname"] = "machine.domain.tld"
This rule will use the Fact
plugin (which is built-in to the core Animal
library) to lookup the certname
key and determines if it is equivalent to "machine.domain.tld"
.
A slightly more complicated rule might look like:
(Fact["machine_class"] = "server" AND Fact["os"] = "ubuntu") OR Fact["awesome"] = true
This rule will again use the Fact
plugin (several times, in fact) to first check if both the machine_class
fact is set to "server"
and the os
fact is set to "ubuntu"
, and only if either of those are false
, the rule determines if the awesome
fact is set to the literal true
value.
There are currently several limitations to the rules syntax, such as:
- Parenthesis are required to force the order of operations for cojunctions (
AND
andOR
), but is not used to determing which is actually applied first. Parenthesis are, in fact, collapsed before any preceeding conjunction is used, but inA OR (B AND C)
, ifA
istrue
then(B AND C)
is never evaluated. - Rules are recursively evaluated with an arity of 2, meaning they are always evaluated as
A then B
whereB
is one or more subrules. This means thatA AND B OR C
is equivalent toA AND (B OR C)
. - Keys sent to plugins, such as
foo
inFact["foo"]
, must be double-quoted and can not contain[
,]
, or"
. - Only these comparison operators are allowed for rules:
=
,!=
,>
,>=
,<
,<=
, andLIKE
. TheLIKE
comparison operator treats the provided value as a regular expression. Do not include the/
before or after the regular expression. - Values used in comparisons must be either literal booleans (
true
orfalse
), a double-quoted string ("foo"
), or an Integer (1
,2
, etc.). Decimals must currently be treated as strings.
Other Rule Components
Besides the rule statement described above, rules also support two additional components, each with two subcomponents. When a rule evaluates to true
, it is said to be applied successfully, so rules have a success
component. Otherwise, rules provide a failure
component for determining what to do when the rule evaluates to false
. Both of these components are considered optional by the rules engine, though a rule that does nothing should be suspect.
Each of these components support adding and subtracting Puppet classes from the final compiled list of classes returned by the ENC. These addition and subtraction operations are gathered then applied after all such operations are determined -- providing the delayed-merging capability of the tool. To add classes based on the outcome of a rule, define an Array of class names (usually roles or profiles) to return in an add
section, either under success
or failure
. Likewise, define a subtract
Array as needed.
When using the YAML storage provider (currently the only supported storage provider for Animal), this could be an example rule:
- :statement: (Fact["machine_class"] = "server" AND Fact["os"] = "ubuntu") OR Fact["awesome"] = true
:success:
:add:
- roles::linux::server
- roles::awesome
:subtract:
- roles::linux::desktop
This rule will add roles::linux::server
and roles::awesome
, and will guarantee that roles::linux::desktop
will not be present in the returned list of Puppet classes if the rule evaluates to true
for a given Puppet node.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/knuedge/animal.
License
The gem is available as open source under the terms of the MIT License.