Feature Friday #14: variablesmatching() & variablesmatching_as_data()

Posted by Nick Anderson
June 14, 2024

Did you know you can find variables by name and tag?

Like the ability to find currently defined classes (as described in Feature Friday #13: classesmatching()) that match a name or tag, you can find variables by name and tag. It’s a nifty capability. variablesmatching() returns a list of variable names that match the name and tag criteria.1 variablesmatching_as_data() returns a data container of the matching variables along with their values2.

Let’s take a look at an example of installing packages.

NOTE: Many different patterns can be used for managing packages. Sometimes, they are managed in a single place. Other times, across multiple bundles. The following example is not intended as a recommendation for any specific pattern. It’s just to illustrate possibilities.

The following bundle defines three lists of packages. Rather than making packages promises for each individually, we collect them - all together - into a single data structure from which we can derive a single list of package names to manage.

/tmp/feature-friday-14/example-0.cf
 bundle agent package_names_from_variablesmatching_as_data
 # @brief Example illustrating deriving a list of package names from variables named with a specific naming convention
{
  vars:
      "packages_baseline" slist => { "bash-completion", "emacs" };
      "packages_os" slist => { "httpd" };
      "packages_barf" slist => { "apache" };

      "_mypkgdata" data => variablesmatching_as_data( ".*\.packages_.*" );

      "_package_names" slist => getvalues( _mypkgdata );

  reports:
      '$(_package_names)';
}

bundle agent __main__
{
      methods: "package_names_from_variablesmatching_as_data";
}
command
cf-agent --no-lock --log-level info --file /tmp/feature-friday-14/example-0.cf
output
R: bash-completion
R: emacs
R: httpd
R: apache

Or, you might prefer to use tags instead of variable names. This allows us to collect information defined across multiple variables, which might even be defined in different bundles or namespaces.

/tmp/feature-friday-14/example-1.cf
bundle agent package_names_from_variablesmatching_as_data
# @brief Example illustrating deriving a list of package names from variables having a specific tag
{
  vars:
      "packages_baseline"
        meta => { "desired_package_names=present" },
        slist => { "bash-completion", "emacs" };

      "packages_os"
        meta => { "desired_package_names=present" },
        slist => { "httpd" };

      "packages_barf"
        meta => { "desired_package_names=present" },
        slist => { "apache" };

      "_mypkgdata" data => variablesmatching_as_data( ".*", "desired_package_names=present" );

      "_package_names" slist => getvalues( _mypkgdata );

  reports:
      '$(_package_names)';

}
bundle agent __main__
{
      methods: "package_names_from_variablesmatching_as_data";
}
command
cf-agent --no-lock --log-level info --file /tmp/feature-friday-14/example-1.cf
output
R: bash-completion
R: emacs
R: httpd
R: apache

Happy Friday! 🎉