Show posts tagged:
policy-language

Feature Friday #42: ob-cfengine3

For the final post in the Feature Friday series I am here to tell you about something I use nearly hourly, ob-cfengine3 which extends Emacs Org Babel for executing CFEngine policy. ob-cfengine3 has been around for a little over seven years now and it has saved me countless hours, seconds at a time. At it’s core it let’s you type a snippet of policy and execute it directly in your document, sort of like Jupyter.

Posted by Nick Anderson
December 27, 2024

Feature Friday #41: How can I quote thee, let me count the ways

Do you enjoy escaping quotes inside strings? I sure don’t, and I really appreciate the flexibility CFEngine provides with 3 different quoting characters (", ', ` ). Let’s take a look. This came up in the post show discussion for The agent is in, episode 39. If you have a string that contains double quotes you might see it written with escaped quotes like this:

Posted by Nick Anderson
December 20, 2024

Feature Friday #40: What would CFEngine do?

CFEngine works by defining a desired state for a given context and converging towards that goal. Given there is no fixed starting point and that the current context might change wildly it can be challenging to succinctly answer the question “What would CFEngine do?”. In Feature Friday #22: Don’t fix, just warn we saw how an individual promise could be made to warn instead of trying to automatically converge towards the desired state, a granular --dry-run mode. This time, let’s take a look at the --simulate option of cf-agent.

Posted by Nick Anderson
December 13, 2024

Handle the state of containers in a Docker compose configuration

Recently we had a Fireside Chat with long-time contributor and CFEngine Champion Bas Van der Vlies. During that talk he mentioned a Build module he developed: promise-type-docker-compose. For this month’s Module Monday post I thought I would take this promise type for a spin alongside the Docker Compose Quickstart tutorial. Setup For this blog I brought up a libvirt vagrant VM with Debian 12 and installed the latest LTS (3.24.0) with cf-remote. To install docker I follow the instructions at Install Docker Engine. I was using Debian 12 “bookworm” and found that the default packages docker.io and docker-compose are rather old and were not compatible with the promise-type-docker-compose module. Additionally, the module relies on the jq utility, so I install that as well. I may write policy some time to take care of these dependencies but especially the Docker Engine install involves quite a few steps so will leave that for another time.

Posted by Craig Comstock
December 2, 2024

Show notes: The agent is in - Episode 43 - Nick & Cody's Thanksgiving Day Special

Nick and Cody celebrate Thanksgiving with a holiday special reviewing some policy related questions Nick recently received. Get the list of all network interfaces present default:sys.interfaces only contains configured interfaces, not configured interfaces. default:sys.interfaces_data at least for Linux systems, this variable contains much more information. /tmp/getindices-sys.interfaces_data.cf bundle agent __main__ { vars: "sys_interfaces_data_keys" slist => getindices( "sys.interfaces_data" ); reports: "$(sys_interfaces_data_keys)"; } command cf-agent --no-lock --log-level info --file /tmp/getindices-sys.interfaces_data.cf output R: lo R: enx0892048803e7 R: enx5cff35c6864b R: wlp0s20f3 R: virbr0 R: docker0 R: br-a7d465b9949b R: vboxnet0 R: tun0 cf-promises can be very useful for reviewing the first order variables that are defined using the --show-vars option.

Posted by Nick Anderson
November 28, 2024

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 #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

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