This site is now 100% read-only, and retired.

cfengine [2/3] : An introduction to cfengine rules

Posted by Steve on Mon 22 Aug 2005 at 19:52

After the previous simple overview of cfengine we'll now look in more detail at the rulefiles, which allow jobs to be conducted both locally and remotely.

The great power of cfengine derives from the fact that you can carry out a wide range of actions within a rule-file.

The main rule file for cfengine is called cfagent.conf, although you can use any filename if you're running the rules manually.

Each rule file is divided into sections which are known as "actions", these actions may then be further separated into classes.

There are two types of actions you can use:

  • "functional actions" which actually do a job.
  • "meta actions" which control how cfengine should work.

As an example the following sample shows one of each of these actions:

control:
        actionsequence = ( files )
        
files:
        /etc/sudoers owner=root group=root mode=0440 action=fixall

Here we have two actions, "control", which is a meta-action giving a list of other actions to run. In this case we're only running the "files" action.

The "files" action specifies the filename /etc/sudoers, and it's intended ownership, group, and permissions along with the job "fixall" to fix these permissions if the are not currently set upon the file on disk.

If you were to save this file to /tmp/sudoers.conf you could execute it manually with :

cfagent -f /tmp/sudoers.conf

(Add -v for verbose output)

As a refinement to the rulefile snippet we've seen already you can also limit actions to particular classes. The general format of the configuration file thus becomes:

#
# comment
#
action-type:
  class::
    actions to take

There are several classes already setup, including host types. So you could setup a file which would work differently upon different machines:

control:
  actionsequence = ( files )

files:
  linux::
     /etc/shadow owner=root group=shadow mode=0440 action=fixall
  sun::
     /etc/shadow owner=root group=root mode=0440 action=fixall

Here we've setup the "files" action to set a different group for the file /etc/shadow on Sun machines than on Linux machines.

The following classes are defined for different operating systems:

ultrix, sun4, sun3, hpux, hpux10, aix, solaris, osf, irix4, irix,
irix64, sco, freebsd, netbsd, openbsd, bsd4_3, newsos, solarisx86, 
aos, nextstep, bsdos linux, debian, cray, unix_sv, GnU, NT.

In addition to these fixed classes you may define your own inside a classes action.

The following is a simple example of defining the class "is_debian" by testing for the file /etc/apt/sources.list:

control:
    actionsequence = ( editfiles )

classes:
    is_debian = ( FileExists(/etc/apt/sources.list) )

editfiles:
   is_debian::
    { 
      /etc/motd
      AppendIfNoSuchLine "Debian Powered by CFEngine!"
    }

This example can be extended to apply rules only on machines which are mail servers, or similar, by testing for a given configuration file.

The ability to define classes by testing for files, etc, is very useful and powerful.

The full list of tests available is included in the manual, but the following are particularly useful:

  • FileExists(/file/path)
    • True if the given file exists.
  • IsDir(/file/path)
    • True if the given file is a directory.

So far we've seen two actions "files", for testing file ownerships, etc, and "editfiles" which allowed us to append a line to a text file. But there are many more available actions.

One useful example is the "disable" action, which can be used to rename files which should be disabled. The full description looks like this:

 disable:
        class::
           /filename
                           dest=filename
                           type=plain/file/link/links
                           rotate=empty/truncate/numerical-value
                           size=numerical-value
                           define=classlist
                           syslog=true/on/false/off
                           inform=true/on/false/off
                           repository=destination directory
                           action=disable/warn
     
                           ifelapsed=mins
                           expireafter=mins
     

Many of these latter options are optional. As most of the options aren't needed most of the time we can see a simple example which disables a file if it's present with this:

disable:
   /etc/hosts.equiv
   /etc/nologin

Or to treat one operating system specially:

disable:
   /etc/hosts.equiv
   /etc/nologin
 sun4::
   /var/spool/cron/at.allow

Another useful action is the "netconfig" setting, which allows you to setup the default route for all your hosts:

control:
  actionsequence = ( netconfig  )
  netmask        = ( 255.255.255.0 )
  InterfaceName  = ( eth1 )

broadcast:
        ones
defaultroute:
  192.168.1.1

Rather than explain further each of the individual settings I'll conclude here, and point you at the full documentation which contains coverage of each of the available actions and their parameters.

The documentation can be found at http://www.cfengine.org/.

In the next, and final, piece we'll show how to install cfengine upon a group of machines with a master host and a number of managed clients.

 

 


Some nice sample rules
Posted by Steve (82.41.xx.xx) on Tue 23 Aug 2005 at 01:41
[ View Weblogs ]

Some nice sample rules can be found here:

Steve
-- Steve.org.uk

[ Parent ]

Another example
Posted by Steve (82.41.xx.xx) on Tue 23 Aug 2005 at 05:10
[ View Weblogs ]

I guess more examples can't hurt:


control:
        actionsequence = ( editfiles processes )
editfiles:
        { /etc/ssh/sshd_config
                ReplaceAll "X11Forwarding no" With "X11Forwarding yes"
                DefineClasses "ssh_restart"
        }
processes:
        ssh_restart::
                "sshd" signal=hup restart "/etc/init.d/ssh"

This enables X11 forwarding, then restarts sshd if it is required.

Steve
-- Steve.org.uk

[ Parent ]

Re: Another example
Posted by bergei (139.105.xx.xx) on Tue 13 Jun 2006 at 14:18
In order to get the restart ssh example to work, you need to add

AddInstallable = ( ssh_restart )

under control:

[ Parent ]