Ever tried to wrangle a fleet of servers with just a text file? Nick shows how CFEngine can take advantage of genders for classification.
In this episode, Nick dives into the configuration file, /etc/genders
. Originally developed by Lawrence Livermore National Laboratory and currently maintained by the Chaos development team, genders often seen in use in High-Performance Computing (HPC) environments. Nick presents two practical examples demonstrating policy implementations, using genders for inventory reporting and grouping hosts.
Video
The video recording is available on YouTube:
At the end of every webinar, we stop the recording for a nice and relaxed, off-the-record chat with attendees. Join the next webinar to not miss this discussion.
Examples
Example illustrating parsing /etc/genders from CFEngine policy
This policy defines g_
prefixed namespace
scoped classes for all attributes (with and without values) and defines variables for attributes with values both tagged for reporting to an Enterprise Hub but only the variables tagged for inventory.
bundle agent __main__
{
methods:
"genders_classification_by_util";
}
bundle agent genders_classification_by_util
# I am assuming that this classification generally only relavent for cf-agent.
# E.g. we won't use one of these classes to guard an access promise sharing some
# directory.
# This policy doesn't handle the installation of the packages necessary to provide nodeattr
{
vars:
# Define a list of all the node attributes for the executing host Including those with values
"my_attrs_list"
slist => string_split( execresult( "nodeattr -l $(sys.uqhost)", useshell, both), "\n", inf ),
if => not( isvariable( $(this.promiser) ) );
# Then we get the list of attributes that don't have a value
"my_attrs_noval" slist => filter( ".*=.*", my_attrs_list, "true", "true", inf );
# Then we get the list of attributes that do have a value
"my_attrs_wval" slist => filter( ".*=.*", my_attrs_list, "true", "false", inf );
"map_attrs_w_val[$(with)]"
string => nth( string_split( "$(my_attrs_wval)", "=", 2 ), 1 ),
meta => { "derived-from=/etc/genders",
"report",
"inventory",
"attribute_name=/etc/genders[$(with)]" },
with => nth( string_split( "$(my_attrs_wval)", "=", 2 ), 0 );
"_map_attrs_w_val_list" slist => getindices( "map_attrs_w_val" );
classes:
"g_$(my_attrs_list)"
meta => { "derived-from=/etc/genders", "report" },
scope => "namespace";
reports:
"Classes defined derived from /etc/genders: $(with)"
with => join( ", ", classesmatching( ".*", "derived-from=/etc/genders" ));
"$(_map_attrs_w_val_list) = $(map_attrs_w_val[$(_map_attrs_w_val_list)])";
}
R: Classes defined derived from /etc/genders: g_linux, g_nickanderson, g_something_value
R: something = value
Example classifying from /etc/genders using utilities (nodeattr)
This policy defines g_
prefixed namespace
scoped classes for all attributes (with and without values) and defines variables for attributes with values both tagged for reporting to an Enterprise Hub but only the variables tagged for inventory.
bundle agent __main__
{
methods:
"genders_classification_by_util";
}
bundle agent genders_classification_by_util
# I am assuming that this classification generally only relavent for cf-agent.
# E.g. we won't use one of these classes to guard an access promise sharing some
# directory.
# This policy doesn't handle the installation of the packages necessary to provide nodeattr
{
vars:
# Define a list of all the node attributes for the executing host Including those with values
"my_attrs_list"
slist => string_split( execresult( "nodeattr -l $(sys.uqhost)", useshell, both), "\n", inf ),
if => not( isvariable( $(this.promiser) ) );
# Then we get the list of attributes that don't have a value
"my_attrs_noval" slist => filter( ".*=.*", my_attrs_list, "true", "true", inf );
# Then we get the list of attributes that do have a value
"my_attrs_wval" slist => filter( ".*=.*", my_attrs_list, "true", "false", inf );
"map_attrs_w_val[$(with)]"
string => nth( string_split( "$(my_attrs_wval)", "=", 2 ), 1 ),
meta => { "derived-from=/etc/genders",
"report",
"inventory",
"attribute_name=/etc/genders[$(with)]" },
with => nth( string_split( "$(my_attrs_wval)", "=", 2 ), 0 );
"_map_attrs_w_val_list" slist => getindices( "map_attrs_w_val" );
classes:
"g_$(my_attrs_list)"
meta => { "derived-from=/etc/genders", "report" },
scope => "namespace";
reports:
"Classes defined derived from /etc/genders: $(with)"
with => join( ", ", classesmatching( ".*", "derived-from=/etc/genders" ));
"$(_map_attrs_w_val_list) = $(map_attrs_w_val[$(_map_attrs_w_val_list)])";
}
R: Classes defined derived from /etc/genders: g_linux, g_nickanderson, g_something_value
R: something = value