Forum: Cfengine Help
Subject: Re: Quickstart guide? [learning more about Cfengine classes]
Author: zzamboni
Link to topic: https://cfengine.com/forum/read.php?3,18464,18493#msg-18493

> How about either nesting classes or having more
> than one condition?

You can have class expressions, in which "." means "and", "|" means "or" and 
"!" means "not".

I can't seem to find a proper description of the class expression syntax in the 
reference manual, but you can see some examples and some other ways of defining 
classes in this section:
http://www.cfengine.org/manuals/cf3-reference.html#classes-in-common-promises

> I need to test
> Am I in Location A
>  Is this test setup
>  Not test setup
> Am I in location B\

You could do something like this, for example. In this case, the list of test 
machines is specified manually, and the location is being detected by IP 
address range, but of course it could be specified by host name, manually in a 
list, or any other criteria.


classes:
  testmachine    or => { "test1", "test2" };
  # assuming locA has 192.168.1.*, locB has 192.168.2.*
  locA        expression => classmatch("IPv4_192\.168\.1\..*");
  locB        expression => classmatch("IPv4_192\.168\.2\..*);


And then, for the conditions you mentioned, your class expressions would be:

  locA.testmachine::
        ...
  locA.!testmachine::
        ...
  locB::
        ...


> Even the "global" files that I will be copying
> have different settings 
> according to location. For example 
> /etc/resolve
> /etc/ntp.conf

One technique to achieve this is what is called "hierarchical copy", in which 
different files may be copied from the same location, depending on a list of 
defined suffixes. I wrote a couple of blog posts about how to do it in 
cfengine3 in my blog:
http://blog.zzamboni.org/implementing-single-copy-nirvana-in-cfengine3
http://blog.zzamboni.org/hierarchical-copying-with-cfengine3

In you case, you could do something like this, using the class definitions from 
before:

vars:
   locA::
      location  string => "locA";
   locB::
      location  string => "locB";
   any::
      suffixes   slist => { ".${location}", "" };

files:
   "/etc/resolv"
       copy_from => mycopy("${repository}/resolv.${suffixes}";

(make sure you have "file_single_copy" set appropriately)

Then, you could have "resolv.locA" and "resolv.locB" in your file repository, 
and the appropriate one will be copied into /etc/resolv depending on the 
machine. The empty string at the end of $(suffixes) means that if no 
location-specific file is found, the "generic" one (without suffix) will be 
copied. Also, $(suffixes) can contain an arbitrary list of values, so you could 
have different types of files for other criteria. For example, if locA and locB 
have different DNS domains, you could simply have suffixes set as follows:

   suffixes    slist => { "$(sys.domain)", "" };

And get rid of setting the $(location) variable (just rename the files to e.g. 
resolv.loca.company.com and resolv.locb.company.com).

> Pros of multiple setups. Each config is simpler.
> Cons of multiple setups. May need to look at
> different places to see all the 
> rules, but I think perhaps a unified version
> control system may somewhat 
> solve the issue.

Cfengine is flexible enough to do it either way. I personally prefer the 
"everyting in a single place" approach, with classes to differentiate the 
actual behavior. Makes it easier to analyze and follow the full policy.

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to