Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions MPF.md
Original file line number Diff line number Diff line change
Expand Up @@ -708,16 +708,39 @@ To override the default for **cf-agent** configure `default:update_def.control_a
The following settings are defined in `controls/def.cf` can be set from an
[augments file][Augments].

### Configure the default promise evaluation order for all components

By default CFEngine processes promises in "Normal Order". Configure `default:def.control_common_evaluation_order` to control the default promise evaluation order for all components (`cf-agent`, `cf-serverd`, `cf-execd` and `cf-monitord`). This variable is used to set `evaluation_order` in `body common control` in `promises.cf`. Override it for a specific component (for example `cf-agent`, see below) or for a specific file (with `evaluation_order` in `body file control`).

Example Augments:

```json
{
"variables": {
"default:def.control_common_evaluation_order": {
"value": "top_down",
"comment": "Our policy writers find it easier to understand policy that is evaluated in the order it is written."
}
}
}
```

**History:**

- Introduced in 3.28.0.

**See also:** [Policy evaluation ordering](reference/language-concepts/policy-evaluation/), [Configure the evaluation order of cf-agent for main policy](#Configure the evaluation order of cf-agent for main policy), [`evaluation_order` in `body common control`][cf-agent#evaluation_order], [Policy style guide on promise ordering][Policy style guide#Promise ordering]

### Configure the evaluation order of cf-agent for main policy

By default CFEngine processes promises in "Normal Order". Configure `default:def.control_agent_evaluation_order` to control the default promise evaluation order for `cf-agent`. This variable is used to set `evaluation_order` in `body agent control` in `promises.cf`
By default `cf-agent` inherits the promise evaluation order from `body common control` (see [Configure the default promise evaluation order for all components](#Configure the default promise evaluation order for all components)). Configure `default:def.control_agent_evaluation_order` to control the promise evaluation order for `cf-agent` specifically, overriding `body common control`. This variable is used to set `evaluation_order` in `body agent control` in `promises.cf` and is only applied when set to a valid value (`classic` or `top_down`) via augments.

Example Augments:

```json
{
"variables": {
"default:def.control_agent_evalution_order": {
"default:def.control_agent_evaluation_order": {
"value": "top_down",
"comment": "Our policy writers find it easier to understand policy that is evaluated in the order it is written."
}
Expand All @@ -728,8 +751,9 @@ Example Augments:
**History:**

- Introduced in 3.27.0.
- Since 3.28.0, `cf-agent` inherits the evaluation order from `body common control` when `default:def.control_agent_evaluation_order` is not set.

**See also:** [Policy evaluation ordering](reference/language-concepts/policy-evaluation/), [Configure cf-agent promise evaluation order for update policy](#Configure the evaluation order for cf-agent evaluated promises for update policy), [Policy style guide on promise ordering][Policy style guide#Promise ordering]
**See also:** [Policy evaluation ordering](reference/language-concepts/policy-evaluation/), [Configure the default promise evaluation order for all components](#Configure the default promise evaluation order for all components), [Configure cf-agent promise evaluation order for update policy](#Configure the evaluation order for cf-agent evaluated promises for update policy), [Policy style guide on promise ordering][Policy style guide#Promise ordering]

### Automatically migrate ignore_interfaces.rx to workdir

Expand Down
12 changes: 8 additions & 4 deletions controls/cf_agent.cf
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ body agent control
# Global default for time that must elapse before promise will be rechecked.
# Don't keep any promises.
any::
@if minimum_version(3.27.0)
# The order in which promises are evaluated (top_down|classic)
evaluation_order => "$(default:def.control_agent_evaluation_order)";
@endif
# Minimum time (in minutes) which should have passed since the last time
# the promise was verified before it is checked again.
ifelapsed => "1";
Expand Down Expand Up @@ -58,4 +54,12 @@ body agent control
# Environment variables based on Distro
control_agent_agentfacility_configured::
agentfacility => "$(default:def.control_agent_agentfacility)";
@if minimum_version(3.27.0)
# Only override cf-agent's promise evaluation order when explicitly
# configured via augments; otherwise cf-agent inherits the order set in
# body common control. See ENT-13495.
control_agent_evaluation_order_configured::
# The order in which promises are evaluated (top_down|classic)
evaluation_order => "$(default:def.control_agent_evaluation_order)";
@endif
}
20 changes: 9 additions & 11 deletions controls/def.cf
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,6 @@ bundle common def
if => and("enterprise_edition", "am_policy_hub");

# Agent Controls
"control_agent_evaluation_order" -> { "ENT-13495" }
string => ifelse(
isvariable($(this.promiser)),
"$(default:def.control_agent_evaluation_order)",
"classic"
),
comment => concat(
'We default to the classic "Normal Order"',
' for cf-agent if not otherwise specified'
);

"control_agent_update_evaluation_order" -> { "ENT-13495" }
string => ifelse(
isvariable($(this.promiser)),
Expand Down Expand Up @@ -451,6 +440,15 @@ bundle common def
" control for setting agentfacility"
);

"control_agent_evaluation_order_configured" -> { "ENT-13495" }
expression => isvariable("default:def.control_agent_evaluation_order"),
comment => concat(
"cf-agent overrides body common control's promise evaluation order",
" only when default:def.control_agent_evaluation_order is set via",
" augments. Otherwise cf-agent inherits the evaluation order from body",
" common control"
);

"_control_agent_environment_vars_validated" -> { "CFE-3927" }
and => {
# The variable must be defined
Expand Down
9 changes: 9 additions & 0 deletions promises.cf.in
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ body common control
# The number of minutes after which last-seen entries are purged from cf_lastseen.lmdb
lastseenexpireafter => "$(def.control_common_lastseenexpireafter)";

@if minimum_version(3.27.0)
# The order in which promises are evaluated (top_down|classic). Sets the
# default evaluation order for all components. Override it for a specific
# component (e.g. cf-agent in body agent control) or file (body file
# control). Defaults to the classic "Normal Order" unless
# default:def.control_common_evaluation_order is set via augments.
evaluation_order => "$(default:def.control_common_evaluation_order)";
@endif

control_common_tls_min_version_defined::
tls_min_version => "$(default:def.control_common_tls_min_version)"; # See also: allowtlsversion in body server control

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Tests that default:def.control_agent_evaluation_order set via augments
# changes cf-agent's promise evaluation order via body agent control
# (ENT-13495).
#
# Only the agent control augment is set. The eo_discriminator bundle (appended
# to the bundlesequence via control_common_bundlesequence_end) prints EARLY
# before LATE in classic (Normal) order, and LATE before EARLY in top_down
# order, so the order of the reports reveals the evaluation order in effect.
body common control
{
inputs => { "../../default.sub.cf" };
bundlesequence => { default("$(this.promise_filename)") };
version => "1.0";
}

#######################################################
bundle agent test
{
vars:
"files_to_copy"
slist => {
"cfe_internal",
"controls",
"inventory",
"lib",
"promises.cf",
"services",
};

files:
"$(sys.inputdir)/." create => "true";

"$(sys.inputdir)/$(files_to_copy)"
copy_from => dcs_sync(
"$(this.promise_dirname)/../../../../$(files_to_copy)"
),
perms => m(600),
depth_search => recurse("inf");

methods:
""
usebundle => file_make(
"$(sys.inputdir)/secondary.cf",
'
bundle agent eo_discriminator
{
reports:
eo_marker::
"ENT13495_EO_EARLY";

classes:
"eo_marker" expression => "any";

reports:
any::
"ENT13495_EO_LATE";
}
'
);

""
usebundle => file_copy(
"$(this.promise_filename).json", "$(sys.inputdir)/def.json"
);
}

#######################################################
bundle agent check
{
vars:
# Only keep the discriminator's reports so the order check is not defeated
# by the (large) rest of the policy output.
"command"
string => "$(sys.cf_agent) -Kf $(sys.inputdir)/promises.cf 2>/dev/null | grep ENT13495_EO";

methods:
# In top_down order LATE is reported before EARLY.
""
usebundle => dcs_passif_output(
"(?s).*ENT13495_EO_LATE.*ENT13495_EO_EARLY.*",
"",
$(command),
$(this.promise_filename)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"inputs": ["$(sys.inputdir)/secondary.cf"],
"vars": { "control_common_bundlesequence_end": ["eo_discriminator"] },
"variables": {
"default:def.control_agent_evaluation_order": { "value": "top_down" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Tests that default:def.control_common_evaluation_order set via augments
# changes the promise evaluation order for all components (ENT-13495).
#
# Here only the common control augment is set (not the agent one), so cf-agent
# must inherit "top_down" from body common control. The eo_discriminator bundle
# (appended to the bundlesequence via control_common_bundlesequence_end) prints
# EARLY before LATE in classic (Normal) order, and LATE before EARLY in top_down
# order, so the order of the reports reveals the evaluation order in effect.
body common control
{
inputs => { "../../default.sub.cf" };
bundlesequence => { default("$(this.promise_filename)") };
version => "1.0";
}

#######################################################
bundle agent test
{
vars:
"files_to_copy"
slist => {
"cfe_internal",
"controls",
"inventory",
"lib",
"promises.cf",
"services",
};

files:
"$(sys.inputdir)/." create => "true";

"$(sys.inputdir)/$(files_to_copy)"
copy_from => dcs_sync(
"$(this.promise_dirname)/../../../../$(files_to_copy)"
),
perms => m(600),
depth_search => recurse("inf");

methods:
""
usebundle => file_make(
"$(sys.inputdir)/secondary.cf",
'
bundle agent eo_discriminator
{
reports:
eo_marker::
"ENT13495_EO_EARLY";

classes:
"eo_marker" expression => "any";

reports:
any::
"ENT13495_EO_LATE";
}
'
);

""
usebundle => file_copy(
"$(this.promise_filename).json", "$(sys.inputdir)/def.json"
);
}

#######################################################
bundle agent check
{
vars:
# Only keep the discriminator's reports so the order check is not defeated
# by the (large) rest of the policy output.
"command"
string => "$(sys.cf_agent) -Kf $(sys.inputdir)/promises.cf 2>/dev/null | grep ENT13495_EO";

methods:
# In top_down order LATE is reported before EARLY.
""
usebundle => dcs_passif_output(
"(?s).*ENT13495_EO_LATE.*ENT13495_EO_EARLY.*",
"",
$(command),
$(this.promise_filename)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"inputs": ["$(sys.inputdir)/secondary.cf"],
"vars": { "control_common_bundlesequence_end": ["eo_discriminator"] },
"variables": {
"default:def.control_common_evaluation_order": { "value": "top_down" }
}
}
Loading