Namespaces are private bundle and body "playgrounds", allowing multiple files to define the bundles and bodies with the same name in different namespaces without conflict. They are key to writing reusable policies.
Everything in CFEngine lives in a namespace (it's the default
namespace if not set).
Specifying a namespace
To isolate a file into its own namespace, you add a control promise to the
file before the relevant bundles or bodies. All bundles and bodies start off in the
default
namespace if you don't explicitly set this. Once set, this applies
until the end of the file or the next namespace change.
body file control
{
namespace => "myspace";
}
Accessing syntax elements between namespaces and the default namespace
To distinguish the bundle mymethod
in the default namespace from one in
another namespace, you prefix the bundle name with the namespace, separated by
a colon.
methods:
"namespace demo" usebundle => myspace:mymethod("arg1");
"namespace demo" usebundle => mymethod("arg1","arg2");
To distinguish a body from one in another namespace, you can prefix the body name with the namespace, separated by a colon.
files:
"/file"
create => "true",
perms => name1:settings;
If you don't make any namespace declarations, you'll be in the
default
namespace. Bundles, bodies, classes, and variables from the
default
namespace can be accessed like any other:
files:
"/file"
create => "true",
perms => default:settings;
If you use the standard library from your own namespace, remember to
specify this default:
prefix.
To access classes, variables, or meta-data in bundles in a different namespace, use the colon as a namespace prefix:
$(namespace:bundle.variable)
$(namespace:bundle_meta.variable)
Note that this means that if you are in a namespace that's not default
, you must qualify classes from default
fully:
default:myclass::
"do something" ifvarclass => "default:myotherclass";
Namespacing of classes and variables created in policy
In policy, you can't create classes outside your own namespace. So
the following, for example, will create the class mynamespace:done
if it runs in the namespace mynamespace
.
files:
"/file"
create => "true",
action => if_repaired("done");
Similarly, variables you create in a namespaced bundle have to be
prefixed like mynamespace:mybundle.myvar
from outside your
namespace, but can use mybundle.myvar
inside the namespace and
myvar
inside mybundle
.
As a workaround, you could have a helper bundle in another namespace to create classes and variables as needed.
Exceptions to namespacing rules
Exceptions to the rules above:
All hard classes can be used as-is from any namespace, without a namespace prefix. These are classes like
linux
. They will have the taghardclass
.All special variable contexts, as documented in Special Variables, are always accessible without a namespace prefix. For example,
this
,mon
,sys
, andconst
fall in this category.