Normal ordering
CFEngine takes a pragmatic point of view to ordering. When promisingscalarattributes and properties, ordering is irrelevant and should not be considered.More complex patterned data structures require ordering to be preserved, e.g.editing in files. CFEngine solves this in a two-part strategy:
CFEngine maintains a default order of promise-types. This is based on a simplelogic of what needs to come first, e.g. it makes no sense to create somethingand then delete it, but it could make sense to delete and then create (anequilibrium). This is called normal ordering and is described below. You canoverride normal ordering in exceptional circumstances by making a promise in aclass context and defining that class based on the outcome of another promise,or using thedepends_on promise attribute.
Agent normal ordering
CFEngine tries to keep variable and class promises before starting to considerany other kind of promise. In this way, global variables and classes can be set.
If you set variables based on classes that are determined by other variables,then you introduce an order dependence to the resolution that might benon-unique.Since CFEngine starts trying to converge values as soon aspossible, it is best to define variables in bundles before using them, i.e.as early as possible in your configuration. In order to make sure all globalvariables and classes are available early enough policy pre-evaluation step wasintroduced.
Policy evaluation overview
CFEngine policy evaluation is done in several steps:
- Classes provided as a command line argument (-D option) are read and set.
- Environment detection and hard classes discovery is done.
- Persistent classes are loaded.
- Policy sanity check using cf-promises -c (full-check) is performed.
- Pre-evaluation step is taking place.
- Exact policy evaluation is done.
For more information regarding each step please see the detailed descriptionbelow.
Policy evaluation details
Before exact evaluation of promises takes place first command line parametersare read and all classes defined using-D parameter are set. Next,environment detection takes place and hard classes are discovered. Whenenvironment detection is complete all the persistent classes are loaded and apolicy sanity check is performed using cf-promises.
cf-promises policy validation step
In this step policy is validated andclasses andvars promises areevaluated. Note that cached functions are executed here, and then again duringthe normal agent execution. Variables and classes resolved in this step do notpersist into the following evaluation step, so all functions will run againduring Agent pre-evaluation.
Agent pre-evaluation step
In order to support expansion of variables in body common control inputs andmake sure all needed classes and variables are determined before they areneeded in normal evaluation, pre-evaluation takes place immediately beforepolicy evaluation.
During pre-evaluation files are loaded based on ordering in body common control(first) and body file control (after body common control). This means thatfiles included in body common control are loaded and parsed before filesplaced in body file control. This is important from a common bundlesevaluation perspective as bundles placed in files included in body commoncontrol inputs will be evaluated before bundles from file control inputs.
The following steps are executed per-bundle for each file parsed, in this order:
- if it's a common bundle, evaluatevars promises
- if it's a common bundle, evaluateclasses promises
- evaluatevars promises(for details see
PolicyResolve()in the C code)
This is done because classes placed in common bundlesare global whereas classes placed in agent bundles are local (by default) tothe bundle where those are defined. This means that common bundlesclasses need these extra steps in order to be resolved for the next steps.
After all policy files are parsed and pre-evaluated, the above pre-evaluationsequence runs once again inorder to help resolve dependencies between classes and vars placed indifferent files.
Agent evaluation step
After pre-evaluation is complete normal evaluation begins.
In this step CFEngine executes agent promise bundles in the strict orderdefined by the bundlesequence (possibly overridden by the-b or--bundlesequence command line option). If the bundlesequence is not providedvia command line argument or is not present in body common control agent willattempt to execute a bundle namedmain. If bundlemain is not defined, theagent will error and exit.
Within a bundle, the promise types are executed in a round-robin fashionaccording to so-callednormal ordering (essentially deletion first, followedby creation). The actual sequence continues for up to three iterations of thefollowing, converging towards a final state:
- meta
- vars
- defaults
- classes
- users
- files
- packages
- guest_environments
- methods
- processes
- services
- commands
- storage
- databases
- reports
- Custom promise types, in written order
Withinedit_line bundles in files promises,the normal ordering is:
The order of promises within one of the above types follows their top-downordering within the bundle itself. In vars this can be used to override thevalue of a variable, if you have two vars promises with the same name, thelast one will override the first one. The order may be overridden by making apromise depend on a class that is set by another promise, or by using thedepends_on attribute in the promise.
Note: The evaluation order of common bundles areclasses, thenvariables and finallyreports. All common bundles are evaluated regardlessif they are placed inbundlesequence or not. Placing common bundles inbundlesequence will cause classes and variables to be evaluated again, and isgenerally good practice to make sure evaluation works properly.
Server normal ordering
As with the agent, common bundles are executed before any server bundles;following this all server bundles are executed (thebundlesequence is onlyused for cf-agent). Within a server bundle, the promise types are unambiguous.Variables and classes are resolved in the same way as the agent. Onconnection, access control must be handled first, then a role request might bemade once access has been granted. Thus ordering is fully constrained byprocess with no additional freedoms.
Within a server bundle, the normal ordering is:
Monitor normal ordering
As with the agent, common bundles are executed before any monitor bundles;following this all monitor bundles are executed (thebundlesequence is onlyused for cf-agent). Variables and classes are resolved in the same way as theagent.
Within a monitor bundle, the normal ordering is:
- Overview
- Getting started
- Reference
- Components
- Functions
- accessedbefore
- accumulated
- ago
- and
- basename
- bundlesmatching
- bundlestate
- callstack_callers
- callstack_promisers
- canonify
- canonifyuniquely
- cf_version_after
- cf_version_at
- cf_version_before
- cf_version_between
- cf_version_maximum
- cf_version_minimum
- changedbefore
- classesmatching
- classfiltercsv
- classify
- classmatch
- concat
- countclassesmatching
- countlinesmatching
- data_expand
- data_readstringarray
- data_readstringarrayidx
- data_regextract
- data_sysctlvalues
- datastate
- difference
- dirname
- diskfree
- escape
- eval
- every
- execresult
- execresult_as_data
- expandrange
- file_hash
- fileexists
- filesexist
- filesize
- filestat
- filter
- findfiles
- findfiles_up
- findprocesses
- format
- getclassmetatags
- getenv
- getfields
- getgid
- getindices
- getuid
- getuserinfo
- getusers
- getvalues
- getvariablemetatags
- grep
- groupexists
- hash
- hash_to_int
- hashmatch
- host2ip
- hostinnetgroup
- hostrange
- hostsseen
- hostswithclass
- hubknowledge
- ifelse
- int
- intersection
- ip2host
- iprange
- irange
- isdir
- isexecutable
- isgreaterthan
- isipinsubnet
- islessthan
- islink
- isnewerthan
- isplain
- isreadable
- isvariable
- join
- lastnode
- laterthan
- ldaparray
- ldaplist
- ldapvalue
- length
- lsdir
- makerule
- maparray
- mapdata
- maplist
- max
- mean
- mergedata
- min
- network_connections
- none
- not
- now
- nth
- on
- or
- packagesmatching
- packageupdatesmatching
- parseintarray
- parsejson
- parserealarray
- parsestringarray
- parsestringarrayidx
- parseyaml
- peerleader
- peerleaders
- peers
- processexists
- product
- randomint
- read_module_protocol
- readcsv
- readdata
- readenvfile
- readfile
- readintarray
- readintlist
- readjson
- readrealarray
- readreallist
- readstringarray
- readstringarrayidx
- readstringlist
- readtcp
- readyaml
- regarray
- regcmp
- regex_replace
- regextract
- registryvalue
- regldap
- regline
- reglist
- remoteclassesmatching
- remotescalar
- returnszero
- reverse
- rrange
- selectservers
- shuffle
- some
- sort
- splayclass
- splitstring
- storejson
- strcmp
- strftime
- string
- string_downcase
- string_head
- string_length
- string_mustache
- string_replace
- string_reverse
- string_split
- string_tail
- string_trim
- string_upcase
- sublist
- sum
- sysctlvalue
- translatepath
- type
- unique
- url_get
- usemodule
- userexists
- validdata
- validjson
- variablesmatching
- variablesmatching_as_data
- variance
- version_compare
- Language concepts
- Masterfiles Policy Framework
- promises.cf
- .no-distrib/
- update.cf
- standalone_self_upgrade.cf
- cfe_internal/
- cfe_internal/CFE_cfengine.cf
- cfe_internal/core/
- cfe_internal/core/watchdog
- cfe_internal/core/watchdog/watchdog.cf
- cfe_internal/enterprise/
- cfe_internal/enterprise/federation/
- cfe_internal/enterprise/federation/federation.cf
- cfe_internal/recommendations.cf
- cfe_internal/update/
- cfe_internal/update/cfe_internal_dc_workflow.cf
- cfe_internal/update/cfe_internal_update_from_repository.cf
- cfe_internal/update/lib.cf
- cfe_internal/update/systemd_units.cf
- cfe_internal/update/update_bins.cf
- cfe_internal/update/update_policy.cf
- cfe_internal/update/update_processes.cf
- controls/
- controls/cf_agent.cf
- controls/cf_execd.cf
- controls/cf_hub.cf
- controls/cf_monitord.cf
- controls/cf_runagent.cf
- controls/cf_serverd.cf
- controls/def.cf
- controls/def_inputs.cf
- controls/reports.cf
- controls/update_def.cf
- controls/update_def_inputs.cf
- inventory/
- inventory/any.cf
- inventory/debian.cf
- inventory/freebsd.cf
- inventory/generic.cf
- inventory/linux.cf
- inventory/lsb.cf
- inventory/macos.cf
- inventory/os.cf
- inventory/redhat.cf
- inventory/suse.cf
- inventory/windows.cf
- lib/
- lib/autorun.cf
- lib/bundles.cf
- lib/cfe_internal.cf
- lib/cfe_internal_hub.cf
- lib/cfengine_enterprise_hub_ha.cf
- lib/commands.cf
- lib/common.cf
- lib/databases.cf
- lib/edit_xml.cf
- lib/event.cf
- lib/examples.cf
- lib/feature.cf
- lib/files.cf
- lib/guest_environments.cf
- lib/monitor.cf
- lib/packages.cf
- lib/paths.cf
- lib/processes.cf
- lib/reports.cf
- lib/services.cf
- lib/stdlib.cf
- lib/storage.cf
- lib/testing.cf
- lib/users.cf
- lib/vcs.cf
- modules/
- modules/mustache/
- modules/packages/
- modules/packages/vendored/
- modules/promises/
- modules/promises/cfengine.py
- modules/promises/cfengine.sh
- services/
- services/autorun/
- services/main.cf
- Macros
- Promise types
- Special variables
- All promise and body types
- Release notes
- Web UI
- Settings
- Health
- Hosts
- Alerts and notifications
- Custom actions for alerts
- Enterprise reporting
- Federated reporting
- Measurements app
- Hub administration
- Decommissioning hosts
- Extending Mission Portal
- Extending query builder in Mission Portal
- Adjusting schedules
- Backup and restore
- Configure a custom LDAP port
- Custom LDAPs certificate
- Custom SSL certificate
- Enable plain http
- Lookup license info
- Policy deployment
- Public key distribution
- Re-installing Enterprise hub
- Regenerate self signed SSL certificate
- Reset administrative credentials
- Debugging Mission Portal
- License
- Examples and tutorials
- Example snippets
- General examples
- Administration examples
- Measuring examples
- Software administration examples
- Commands, scripts, and execution examples
- File and directory examples
- File template examples
- Interacting with directory services
- Database examples
- Network examples
- System security examples
- System information examples
- System administration examples
- System file examples
- Windows registry examples
- File permissions
- User management examples
- Common promise patterns
- Aborting execution
- Change detection
- Check filesystem space
- Copy single files
- Create files and directories
- Customize message of the day
- Distribute ssh keys
- Ensure a process is not running
- Ensure a service is enabled and running
- Find the MAC address
- Install packages
- Mount NFS filesystem
- Restart a process
- Set up name resolution with DNS
- Set up sudo
- Set up time management through NTP
- Updating from a central policy server
- Tutorials
- JSON and YAML support in CFEngine
- Installing CFEngine Enterprise agent
- Managing local users
- Managing network time protocol
- Managing processes and services
- Package management
- Writing CFEngine policy
- Distributing files from a central location
- File editing
- Reporting and remediation of security vulnerabilities
- Masterfiles Policy Framework upgrade
- Tags for variables, classes, and bundles
- Custom inventory
- Dashboard alerts
- Integrating alerts with PagerDuty
- Integrating alerts with ticketing systems
- Integrating with Sumo Logic
- Rendering files with Mustache templates
- Reporting
- File comparison
- High availability
- Writing and serving policy
- Example snippets
- Resources
- FAQ
- Why knowledge management?
- Requesting a CFEngine Enterprise License
- Uninstalling / reinstalling
- Agent output email
- Debugging slow queries
- Enterprise Report Filtering
- Enterprise report collection
- Enterprise reporting database
- How can I tell what classes and variables are defined?
- How do I find the public key for a given host
- How do I fix trust after an IP change?
- How do I fix undefined body errors?
- How do I integrate custom policy?
- How do I pass a data type variable?
- Manual execution
- Mustache templating
- Unable to log into Mission Portal
- Users
- What is promise locking?
- Why are remote agents not updating?
- Why are some files inside masterfiles not being updated/distributed?
- Why does CFEngine install into /var/cfengine instead of following the FHS?
- Bootstrapping
- Tuning PostgreSQL
- What did CFEngine do?
- External resources
- Additional topics
- Best practices
- FAQ
- API
- Enterprise API examples
- Enterprise API reference
- Actions API
- Build API
- CMDB API
- Changes REST API
- Federated reporting configuration API
- File changes API
- Health diagnostic API
- Host REST API
- Import & export API
- Import & export compliance report API
- Inventory API
- LDAP authentication API
- Personal groups API
- Query REST API
- SQL schema
- SSH keys API
- Shared groups API
- Status and settings REST API
- Two-factor authentication API
- Users and access-control REST API
- VCS settings API
- Web RBAC API