When executing commands in a shell, the program and its arguments are typically separated by spaces. This command reads the content of two files and prints it out (concatenating it):
command cat one.txt two.txt In the example above, cat is the command / program, while one.txt is the first argument, and two.txt is the second argument. This is great because it makes commands really easy to read and type, however there is one obvious drawback: When a space has a special meaning (separating arguments), what do you do when you actually need a space?
To manage large infrastructures, efficient solutions for both making changes and observing the current state are necessary. As most information (inventory) about hosts is quite predictable and static, there are many opportunities for optimizations in terms of compression and avoiding re-transmission of the same data. In the CFEngine team, we are improving our reporting systems with a focus on correctness and low bandwidth consumption. This will benefit many users, both large data centers where bandwidth (networking equipment) is costly, as well as small IoT devices with limited connectivity. Inspired by git, we are implementing commits of reporting data, with table-based diffs, and compression of multiple changes, akin to squashing git commits.
We want to bring to your attention a critical security matter recently identified in CFEngine Enterprise version 3.6.0 and subsequent releases. This vulnerability pertains to a A03:2021 - Injection flaw within the CFEngine Enterprise web UI, Mission Portal, which can lead to unauthorized access to the underlying database. The CVE identifier CVE-2023-45684 has been assigned to this issue. At present, there is no evidence to suggest that this vulnerability has been exploited or that it was known beyond the CFEngine development team and the customer who brought it to our attention.
Opening and reading files may cause your program to block indefinitely. In this blogpost we'll discuss how to work around this issue.
Our beloved cfbs CLI tool for working with CFEngine Build is rapidly evolving. At the time of writing, we are currently at version 3.2.1. Thus I would like to take this opportunity to talk a bit about the latest and greatest features; including support for users to manipulate input parameters in modules, as well as a couple of new build steps.
If you haven’t yet got a hold of the latest version of cfbs, you can update it with pip using the following command:
In the upcoming CFEngine 3.20 release we are making a change in the behaviour of the create attribute for the files promises that manage the entire content of a file. This includes promises with the template methods mustache, inline_mustache and cfengine; as well as promises with the content attribute.
The motivation behind these new changes is two-fold; make it easier to learn CFEngine policy language and understand what policy is doing, and to prevent CFEngine from creating empty configuration files.
Last year we had a look at managing local groups with the custom groups promise type. As you may or may not recall, we used JSON-strings to imitate CFEngine bodies. This was due to the fact that the promise module protocol did not support bodies at that time. Today, on the other hand, we’re happy to announce that as of CFEngine 3.20, this will no longer be the case. In this blog post we’ll introduce the long awaited feature; custom bodies. We’ll have a look at it from both the policy writers- and the promise module developers point of view.
Manually managing groups on a large infrastructure can be a tedious task, and is therefore best suited through automation software like CFEngine. Unfortunately - at time of writing - CFEngine does not have any built-in promise types for managing groups. But fear not; in CFEngine 3.17, custom promise types were introduced. This new exhilarating feature does not only allow for members of our community to make their own custom promise types, but also lets the CFEngine Core developers prototype new future promise types. In this blog post, I’d like to introduce one of our prototypes; the experimental groups promise type.
I recently had a minor task involving changing an option - on one of our command line tools - from taking a required argument, to taking an optional argument. This should be easy they said; just change the respective option struct to take an optional argument, add a colon to the optstring, and get on with your life.
Well, it proved to be easier said than done. My initial expectation was that a solution similar to the one below should just work. And it does work, just not in the way I expected.