Namespaces

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 tag hardclass.

  • All special variable contexts, as documented in Special Variables, are always accessible without a namespace prefix. For example, this, mon, sys, and const fall in this category.