Feature Friday #19: What variables and classes are defined?

Posted by Nick Anderson
July 19, 2024

Do you know how to quickly see what variables and classes are defined?

Often, while developing CFEngine policy it’s convenient to emit a variable value or a report based on the presence of a class. For example:

bundle agent main
{
  reports:
    "Unqualified hostname = '$(sys.uqhost)'";
    linux::
      "I am running on linux";
}

In some cases, this is because you are exploring what classes are available. In other cases, it might be DEBUG-related reports helping you understand how a variable is resolved during policy evaluation. Often, you can get this information without writing CFEngine policy to emit it by using the --show-vars or --show-classes options to cf-promises.

You can even filter the output. For example, here we show vars matching sys.uqhost and classes matching linux.

command
cf-promises --show-vars=sys.uqhost --show-classes=linux
output
Class name                                                   Meta tags                                Comment
compiled_on_linux_gnu                                        source=agent,hardclass
linux                                                        inventory,attribute_name=none,source=agent,derived-from=sys.class,hardclass
linux_6_1_72_060172_generic                                  inventory,attribute_name=none,source=agent,derived-from=sys.sysname,derived-from=sys.release,hardclass
linux_x86_64                                                 source=agent,derived-from=sys.sysname,derived-from=sys.machine,hardclass
linux_x86_64_6_1_72_060172_generic                           source=agent,derived-from=sys.sysname,derived-from=sys.machine,derived-from=sys.release,hardclass
linux_x86_64_6_1_72_060172_generic__202401101633_SMP_PREEMPT_DYNAMIC_Wed_Jan_10_16_59_46_UTC_2024 source=agent,derived-from=sys.long_arch,hardclass
specific_linux_os                                            source=promise
Variable name                            Variable value                                               Meta tags                                Comment
default:sys.uqhost                       precision-5570                                               inventory,source=agent,attribute_name=none

Now, cf-promises do not perform a “full” policy execution. Hence, variables or classes getting defined during the policy evaluation, will not get resolved. In those cases, you might prefer to use the --show-evaluated-vars and --show-evaluated-classes options to cf-agent. It works similarly to the related options to cf-promises but the variables and classes are emitted after the agent completes policy execution. Also, note that only namespace (aka. globally scoped) classes are visible in this output. Ephemeral bundle scoped classes will not be shown. This example illustrates that:

/tmp/feature-friday-19.cf
bundle agent main
{
  vars:
    "MyString" string => "MyValue";
    "MyList" slist => { "one", "two" };

  classes:
    "bundle_scoped_class"
        expression => "any",
        scope => "bundle";

    "namespace_scoped_class"
        expression => "any",
        scope => "namespace";
}

Running it, we filter for variables starting with My in the main bundle of the default namespace and classes ending in _scoped_class:

command
cf-agent -Kf /tmp/feature-friday-19.cf \
         --show-evaluated-vars=default:main\.My \
         --show-evaluated-classes=.*_scoped_class
output
Class name                                                   Meta tags                                Comment
namespace_scoped_class                                       source=promise
Variable name                            Variable value                                               Meta tags                                Comment
default:main.MyList                       {"one","two"}                                               source=promise
default:main.MyString                    MyValue                                                      source=promise

Happy Friday! 🎉