Show posts by author:
Nick Anderson

Feature Friday #37: Decisions based on arbitrary semantic versions

Ever need to make a decision based on the version of something? The version_compare() function might be useful for you.1 Over time, software changes and features are added and removed. Sometimes, we need to make a decision based on versions. For example, the Include directive in ssh_config was introduced in OpenSSH 7.3.2 Let’s take a look at how we could possibly use it. This example illustrates the basic use of version_compare():

Posted by Nick Anderson
November 22, 2024

Feature Friday #36: Formatting policy with cffmt

Looking for a tool to help you format your CFEngine policy? Have you heard of cffmt? You might recall that we had a chat with the author, Miek Gieben in The agent is in - Episode 24.1 In case you missed it, cffmt is a command line tool for formatting CFEngine policy files, like gofmt for .cf files.2 Let’s take a look. Consistent formatting can really ease reading of policy, but sometimes editors are configured differently and you can end up with inconsistently formatted policy. For example, here is a contrived policy file with some irregular formatting:

Posted by Nick Anderson
November 15, 2024

Feature Friday #35: Groups in Mission Portal

Have you seen the new Groups feature in CFEngine Enterprise Mission Portal? It was first released in 3.23.0 and it’s part of the 3.24 LTS series released earlier this year, let’s check it out. Groups in Mission Portal can be based on any host reported data. They can be dynamic (hosts can come and go from a group) or they can be static and tied to specific hosts by hostname, mac address, IP or CFEngine’s public key. By default groups are not shared with other users and they can be used any place where you would use a filter constraining the scope of hosts based on various conditions related to the hosts reported data. If a group is shared it can have data associated with it.

Posted by Nick Anderson
November 8, 2024

Feature Friday #34: Self organizing groups with select_class

Did you know CFEngine can self-organize hosts into different groups? Say you have a few hosts that you want to reboot once a month. You don’t care when, but you want the hosts to self-organize and pick a date. The select_class attribute for classes type promises might be what you’re looking for. Let’s take a look. We’ll keep things simple, so we want each host to self-select a day of the month (1-28).

Posted by Nick Anderson
November 1, 2024

Show notes: The agent is in - Episode 42 - Fireside Chat w/ Bas Van der Vlies

The prolific contributor and CFEngine Champion Bas Van der Vlies joins the team for a chat about his history and experience with CFEngine dating back to version 1.0.3. For this special Halloween edition Bas joined Cody, Craig and Nick to reflect on his journey getting into information technology beginning with chemical engineering through joining the Dutch National Compute Center where he was managing many SGI and AIX machines and where he discovered CFEngine and how it could help him manage all the machines. Bas went on to highlight some of his favorite features and discussed how CFEngine has evolved over the years. His advice for both new and old users is to check out some of the newer tooling like cf-remote and cfbs for the CFEngine Build system as they can dramatically help to simplify policy maintenance.

Posted by Nick Anderson
October 31, 2024

Feature Friday #33: Why associative arrays when data containers exist?

What’s the difference between an associative array and a data container in CFEngine? CFEngine has two ways in which structured data can be used, associative arrays (sometimes called classic arrays) and data containers. Let’s take a look at a simple data structure. Here we have two data structures, a_email an associative array and d_email a data container. The policy emits the JSON representation of each. bundle agent __main__ { vars: "a_email[john@example.com][FirstName]" string => "John"; "a_email[john@example.com][LastName]" string => "Doe"; "d_email" data => '{ "john@example.com": { "FirstName": "John", "LastName": "Doe" } }'; reports: "JSON representation of a_email (associateve array):$(const.n)$(with)" with => storejson( a_email ); "JSON representation of d_email (data container):$(const.n)$(with)" with => storejson( d_email ); } Looking at the output, they are identical:

Posted by Nick Anderson
October 25, 2024

Feature Friday #32: Doing math in policy with eval()

Ever need to do some math during policy evaluation? Sometimes configuration settings are based on available resources. For example, what if you want to calculate the size of shared buffers to be 25% of your available memory? Let’s write some policy. First, we need to figure out how much memory we have. Let’s parse this out from /proc/meminfo: bundle agent __main__ { vars: "d_meminfo" data => data_readstringarray( "/proc/meminfo", "", "(:|\s+)", inf, inf); reports: "$(with)" with => storejson( "d_meminfo[MemTotal]" ); } R: [ "", "65505464", "kB" ] So, we have 65505464 kB of memory in total. Knowing that we can use eval() to calculate what 25% is.

Posted by Nick Anderson
October 18, 2024

Feature Friday #31: Seeing a data structure with storejson()

Ever need to visualize the data your working with? storejson() to the rescue! Let’s re-visit our example for sys.os_release from Feature Friday #12: Special variables: bundle agent __main__ { reports: "My custom key 'NORTHERN_TECH_OWNER' contains $(sys.os_release[NORTHERN_TECH_OWNER])"; } R: My custom key 'NORTHERN_TECH_OWNER' contains Nick Anderson So, we saw the value of a single key, but if we don’t know what keys are available it can be useful to render the JSON representation. The with attribute in combination with storejson() provides a convenient way to visualize the JSON representation of structured data in CFEngine. Let’s adjust the policy:

Posted by Nick Anderson
October 11, 2024

Feature Friday #30: Agent svg

Ever want a custom CFEngine Agent logo? Check out agentsvg. You can find agentsvg in core/contrib/ it’s a python script that can generate CFEngine agent logos. python3 ./agentsvg.py > agent.svg python3 ./agentsvg.py --body="#f5821f" --head="#052569" > agent-body-head-colors.svg In addition to customizing the head and body colors you can customize the arm positions to be up, down, out or angled and the legs can be straight or out python3 ./agentsvg.py --arms angled --legs out > agent-arms-legs.svg Happy Friday! 🎉

Posted by Nick Anderson
October 4, 2024

Feature Friday #29: Variable class expressions

Did you know you can use variables in class expressions? If you are reading this, you probably are already familiar with the ability to use class expressions to restrict the context of multiple promises. For example, here we have three reports type promises, all guarded by the class expression linux::. bundle agent __main__ { reports: linux:: "Only hosts with the linux class"; "Will have these promises"; "In context"; } And, if you are tracking this series, you know that you can restrict the context of a single promise using if or unless.1 However, you can also use variables in class expressions. Let’s take a look.

Posted by Nick Anderson
September 27, 2024