- Pull request: #452
- Availability: cfengine/master branch
A multi-level if-else like statement.
body common control
{
bundlesequence => { "example" };
}
###########################################################
bundle agent example
{
classes:
"myclass" expression => "any";
"myclass2" expression => "any";
"secondpass" expression => "any";
vars:
# result: { "1", "single string parameter", "hardclass OK", "bundle class OK", "5 parameters OK" }
# we need to use the secondpass class because on the first pass,
# myclass and myclass2 are not defined yet
secondpass::
"mylist" slist => {
ifelse(1),
ifelse("single string parameter"),
ifelse("cfengine", "hardclass OK", "hardclass broken"),
ifelse("myclass.myclass2", "bundle class OK", "bundle class broken"),
ifelse("this is not true", "5 parameters broken",
"this is also not true", "5 parameters broken 2",
"5 parameters OK"),
};
reports:
"ifelse result list: $(mylist)";
}
Output
Running full policy integrity checks
R: ifelse result list: 1
R: ifelse result list: single string parameter
R: ifelse result list: hardclass OK
R: ifelse result list: bundle class OK
R: ifelse result list: 5 parameters OK
As usual, another example: imagine we have servers over the world, and the only way to get their location is to look at the subnet they belong to, as follows:
- 192.168.10.0/24: France
- 192.168.50.0/24: Germany
- 192.168.100.0/24: Spain
- 192.168.200.0/24: England
We want to report their country, and report “unknown” when the subnet is not among the ones above.
One way to do this:
body common control
{
bundlesequence => { "country" };
}
bundle agent country
{
vars:
ipv4_192_168_10::
"country" string => "france",
policy => "free";
ipv4_192_168_50::
"country" string => "germany",
policy => "free";
ipv4_192_168_100::
"country" string => "spain",
policy => "free";
ipv4_192_168_200::
"country" string => "england",
policy => "free";
!known_subnet::
"country" string => "unknown",
policy => "free";
classes:
"known_subnet" or => {
"ipv4_192_168_10",
"ipv4_192_168_50",
"ipv4_192_168_100",
"ipv4_192_168_200"
};
reports:
"My location is $(country)";
}
Forcing a class, to be in Spain:
cf-agent -KIf country.cf -D ipv4_192_168_100
Running full policy integrity checks
R: My location is spain
This is where ifelse() is handy to handle multiples tests and one default case less verbosely:
body common control
{
bundlesequence => { "country" };
}
bundle agent country
{
vars:
"country" string => ifelse("ipv4_192_168_10", "france",
"ipv4_192_168_50", "germany",
"ipv4_192_168_100", "spain",
"ipv4_192_168_200", "england",
"unknown");
reports:
"My location is $(country)";
}
Running it…
$ cf-agent -KIf country_ifelse.cf -D ipv4_192_168_100
Running full policy integrity checks
R: My location is spain
And finally “unknown” country (depending the subnet of your computer, your output may vary):
$ cf-agent -KIf country.cf
Running full policy integrity checks
R: My location is unknown
$ cf-agent -KIf country_ifelse.cf
Running full policy integrity checks
R: My location is unknown
Links to country.cf country_ifelse.cf