1# All software in this repository except where explicitly marked otherwise is
2# under the following license.
3
4################################################################################
5# MIT Public License
6# http://www.opensource.org/licenses/MIT
7
8# Copyright 2021 Northern.tech AS
9
10# Permission is hereby granted, free of charge, to any person obtaining a copy of
11# this software and associated documentation files (the "Software"), to deal in
12# the Software without restriction, including without limitation the rights to
13# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14# the Software, and to permit persons to whom the Software is furnished to do so,
15# subject to the following conditions:
16
17# The above copyright notice and this permission notice shall be included in all
18# copies or substantial portions of the Software.
19
20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
23# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26################################################################################
27
28################################################################################
29# If you find CFEngine useful, please consider purchasing a commercial version
30# of the software.
31################################################################################
32
33################################################################################
34#
35#   promises.cf - Basic Policy for CFEngine
36#
37################################################################################
38
39body common control
40# @brief Control options common to all agents
41{
42
43      bundlesequence => {
44                        # Common bundle first (Best Practice)
45                          inventory_control,
46                          @(inventory.bundles),
47                          def,
48                          @(cfengine_enterprise_hub_ha.classification_bundles),
49
50                          # Custom classification
51                          @(def.bundlesequence_classification),
52
53                          # autorun system
54                          services_autorun,
55                          @(services_autorun.bundles),
56
57                         # Agent bundle
58                          cfe_internal_management,   # See cfe_internal/CFE_cfengine.cf
59                          main,
60                          @(cfengine_enterprise_hub_ha.management_bundles),
61                          @(def.bundlesequence_end),
62
63      };
64
65      inputs => {
66                  # User policy init, for example for defining custom promise types:
67                  "services/init.cf",
68
69                 # File definition for global variables and classes
70                  @(cfengine_controls.def_inputs),
71
72                # Inventory policy
73                  @(inventory.inputs),
74
75                 # CFEngine internal policy for the management of CFEngine itself
76                  @(cfe_internal_inputs.inputs),
77
78                 # Control body for all CFEngine robot agents
79                  @(cfengine_controls.inputs),
80
81                 # COPBL/Custom libraries.  Eventually this should use wildcards.
82                  @(cfengine_stdlib.inputs),
83
84                  # autorun system
85                  @(services_autorun.inputs),
86
87                  "services/main.cf",
88      };
89
90      version => "CFEngine Promises.cf @VERSION@";
91
92      # From 3.7 onwards there is a new package promise implementation using package
93      # modules in which you MUST provide package modules used to generate
94      # software inventory reports. You can also provide global default package module
95      # instead of specifying it in all package promises.
96    (debian).!disable_inventory_package_refresh::
97          package_inventory => { $(package_module_knowledge.platform_default) };
98
99      # We only define pacakge_invetory on redhat like systems that have a
100      # python version that works with the package module.
101    (redhat|centos|suse|sles|opensuse|amazon_linux).cfe_yum_package_module_supported.!disable_inventory_package_refresh::
102        package_inventory => { $(package_module_knowledge.platform_default) };
103
104    (debian|redhat|suse|sles|opensuse|amazon_linux)::
105          package_module => $(package_module_knowledge.platform_default);
106
107      # CFEngine 3.12.2+ and 3.14+ have new package module on Windows
108    windows.cfengine_3_12.!(cfengine_3_12_0|cfengine_3_12_1)::
109          package_inventory => { $(package_module_knowledge.platform_default) };
110          package_module => $(package_module_knowledge.platform_default);
111@if minimum_version(3.14)
112    windows::
113          package_inventory => { $(package_module_knowledge.platform_default) };
114          package_module => $(package_module_knowledge.platform_default);
115@endif
116    termux::
117          package_module => $(package_module_knowledge.platform_default);
118
119    alpinelinux::
120          package_module => $(package_module_knowledge.platform_default);
121
122
123    any::
124        ignore_missing_bundles => "$(def.control_common_ignore_missing_bundles)";
125        ignore_missing_inputs => "$(def.control_common_ignore_missing_inputs)";
126
127
128}
129
130bundle common inventory
131# @brief Set up inventory inputs
132#
133# This bundle creates the inputs for inventory bundles.
134#
135# Inventory bundles are simply common bundles loaded before anything
136# else in promises.cf
137#
138# Tested to work properly against 3.5.x
139{
140  classes:
141      "other_unix_os" expression => "!(windows|macos|linux|freebsd|aix)";
142      "specific_linux_os" expression => "redhat|debian|suse|sles";
143
144  vars:
145      # This list is intended to grow as needed
146    debian::
147      "inputs" slist => { "inventory/any.cf", "inventory/linux.cf", "inventory/lsb.cf", "inventory/debian.cf", "inventory/os.cf" };
148      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_linux", "inventory_lsb", "inventory_debian", "inventory_os" };
149    redhat::
150      "inputs" slist => { "inventory/any.cf", "inventory/linux.cf", "inventory/lsb.cf", "inventory/redhat.cf", "inventory/os.cf" };
151      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_linux", "inventory_lsb", "inventory_redhat", "inventory_os" };
152    suse|sles::
153      "inputs" slist => { "inventory/any.cf", "inventory/linux.cf", "inventory/lsb.cf", "inventory/suse.cf", "inventory/os.cf" };
154      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_linux", "inventory_lsb", "inventory_suse", "inventory_os" };
155    windows::
156      "inputs" slist => { "inventory/any.cf", "inventory/windows.cf", "inventory/os.cf" };
157      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_windows", "inventory_os" };
158    macos::
159      "inputs" slist => { "inventory/any.cf", "inventory/macos.cf", "inventory/os.cf" };
160      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_macos", "inventory_os" };
161    freebsd::
162      "inputs" slist => { "inventory/any.cf", "inventory/freebsd.cf", "inventory/os.cf" };
163      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_freebsd", "inventory_os" };
164    linux.!specific_linux_os::
165      "inputs" slist => { "inventory/any.cf", "inventory/linux.cf", "inventory/lsb.cf", "inventory/os.cf" };
166      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_linux", "inventory_lsb", "inventory_os" };
167    aix::
168      "inputs" slist => { "inventory/any.cf", "inventory/generic.cf", "inventory/aix.cf", "inventory/os.cf" };
169      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_generic", "inventory_aix", "inventory_os" };
170    other_unix_os::
171      "inputs" slist => { "inventory/any.cf", "inventory/generic.cf", "inventory/os.cf" };
172      "bundles" slist => { "inventory_control", "inventory_any", "inventory_autorun", "inventory_generic", "inventory_os" };
173
174  reports:
175    verbose_mode::
176      "$(this.bundle): loading inventory module '$(inputs)'";
177}
178
179      #
180
181bundle common cfe_internal_inputs
182# @brief Include internal self management policies
183{
184  vars:
185    any::
186
187      "input[cfe_internal_management]"
188        string => "cfe_internal/CFE_cfengine.cf",
189        comment => "This policy activates internal management policies
190                    for both core and enterprise";
191
192      "input[core_main]"
193        string => "cfe_internal/core/main.cf",
194        comment => "This policy activates other core policies";
195
196      "input[core_limit_robot_agents]"
197        string => "cfe_internal/core/limit_robot_agents.cf",
198        comment => "The policy here ensures that we don't have too many
199                    cf-monitord or cf-execd processes";
200
201      "input[core_log_rotation]"
202        string => "cfe_internal/core/log_rotation.cf",
203        comment => "This policy ensures that various cfengine log files
204                    do not grow without bound and fill up the disk";
205
206      "input[core_host_info_report]"
207        string => "cfe_internal/core/host_info_report.cf",
208        comment => "This policy produces a text based host info report
209                    and serves as a functional example of using mustache templates";
210
211      "input[cfengine_internal_core_watchdog]"
212        string => "cfe_internal/core/watchdog/watchdog.cf",
213        comment => "This policy configures external watchdogs to ensure that
214                    cf-execd is always running.";
215
216    enterprise_edition.(policy_server|am_policy_hub)::
217
218      "input[enterprise_hub_specific]"
219        string => "cfe_internal/enterprise/CFE_hub_specific.cf",
220        comment => "Policy relating to CFEngine Enterprise Hub, for example
221                    software updates, webserver configuration, and alerts";
222
223@if minimum_version(3.12.0)
224      "input[enterprise_hub_federation]"
225        string => "cfe_internal/enterprise/federation/federation.cf",
226        comment => "Policy relating to CFEngine Federated Reporting";
227@endif
228
229    enterprise_edition::
230
231      "input[enterprise_knowledge]"
232        string => "cfe_internal/enterprise/CFE_knowledge.cf",
233        comment => "Settings mostly releated to CFEngine Enteprise Mission Portal";
234
235      "input[enterprise_main]"
236        string => "cfe_internal/enterprise/main.cf",
237        comment => "This policy activates other enterprise specific policies";
238
239      "input[change_management]"
240        string => "cfe_internal/enterprise/file_change.cf",
241        comment => "This policy monitors critical system files for change";
242
243      "input[enterprise_mission_portal]"
244        string => "cfe_internal/enterprise/mission_portal.cf",
245        comment => "This policy manages Mission Portal related configurations.";
246
247    any::
248      "inputs" slist => getvalues("input");
249}
250
251bundle common cfengine_stdlib
252# @brief Include the standard library
253{
254  vars:
255
256    any::
257      "inputs" slist => { "$(sys.local_libdir)/stdlib.cf" };
258
259
260      # As part of ENT-2719 3.12.2 introduced package_method attributes for
261      # specifying the interpreter and specifying the module path. These
262      # attributes are not known in previous versions and must not be seen by
263      # the parser or they will be seen as syntax errors. A cleaner way to do
264      # this using the minimum_version macro is possible, but that would break
265      # masterfiles compatibility in 3.12 with 3.7 binaries since 3.7 binaries
266      # do not support major.minor.patch with minimum_version, only major.minor.
267
268    windows.cfengine_3_12.!(cfengine_3_12_0|cfengine_3_12_1)::
269      "inputs" slist => { "$(sys.local_libdir)/stdlib.cf",
270                          "$(sys.local_libdir)/packages-ENT-3719.cf" };
271@if minimum_version(3.14)
272    windows::
273      "inputs" slist => { "$(sys.local_libdir)/stdlib.cf",
274                          "$(sys.local_libdir)/packages-ENT-3719.cf" };
275@endif
276
277  reports:
278    verbose_mode::
279      "$(this.bundle): defining inputs='$(inputs)'";
280}
281
282bundle common cfengine_controls
283# @brief Include various agent control policies
284{
285  vars:
286
287      "def_inputs"
288        slist => {
289                   "controls/def.cf",
290                   "controls/def_inputs.cf",
291                 },
292        comment => "We strictly order the def inputs because they should be parsed first";
293
294
295      "input[cf_agent]"
296        string => "controls/cf_agent.cf",
297        comment => "Agent control options";
298
299      "input[cf_execd]"
300        string => "controls/cf_execd.cf",
301        comment => "Executor (scheduler) control options";
302
303      "input[cf_monitord]"
304        string => "controls/cf_monitord.cf",
305        comment => "Monitor/Measurement control options";
306
307      "input[cf_serverd]"
308        string => "controls/cf_serverd.cf",
309        comment => "Server control options";
310
311      "input[cf_runagent]"
312        string => "controls/cf_runagent.cf",
313        comment => "Runagent (remote activation request) control options";
314
315    enterprise_edition::
316
317      "input[cf_hub]" -> { "CFEngine Enterprise" }
318        string => "controls/cf_hub.cf",
319        comment => "Hub (agent report collection) control options";
320
321      "input[reports]" -> { "CFEngine Enterprise" }
322        string => "controls/reports.cf",
323        comment => "Report collection options";
324
325    any::
326
327      "inputs" slist => getvalues(input);
328
329  reports:
330    DEBUG|DEBUG_cfengine_controls::
331      "DEBUG $(this.bundle)";
332        "$(const.t)defining inputs='$(inputs)'";
333}
334
335bundle common services_autorun
336# @brief Include autorun policy and discover autorun bundles if enabled
337#
338# Files inside directories listed in `def.mpf_extra_autorun_inputs` will be
339# added to inputs automatically.
340{
341  vars:
342    services_autorun|services_autorun_inputs::
343      "_default_autorun_input_dir"
344        string => "$(this.promise_dirname)/services/autorun";
345      "_default_autorun_inputs"
346        slist => lsdir( "$(_default_autorun_input_dir)", ".*\.cf", "true");
347
348      "_extra_autorun_input_dirs"
349        slist => { @(def.mpf_extra_autorun_inputs) },
350        if => isvariable( "def.mpf_extra_autorun_inputs" );
351
352      "_extra_autorun_inputs[$(_extra_autorun_input_dirs)]"
353        slist => lsdir("$(_extra_autorun_input_dirs)/.", ".*\.cf", "true"),
354        if => isdir( $(_extra_autorun_input_dirs) );
355
356      "found_inputs" slist => { @(_default_autorun_inputs),
357                                sort( getvalues(_extra_autorun_inputs), "lex") };
358
359    !(services_autorun|services_autorun_inputs|services_autorun_bundles)::
360      # If services_autorun is not enabled, then we should not extend inputs
361      # automatically.
362      "inputs" slist => { };
363      "found_inputs" slist => {};
364      "bundles" slist => { "services_autorun" }; # run self
365
366    services_autorun|services_autorun_inputs|services_autorun_bundles::
367      "inputs" slist => { "$(sys.local_libdir)/autorun.cf" };
368      "bundles" slist => { "autorun" }; # run loaded bundles
369
370  reports:
371    DEBUG|DEBUG_services_autorun::
372      "DEBUG $(this.bundle): Services Autorun Disabled"
373        if => "!(services_autorun|services_autorun_bundles|services_autorun_inputs)";
374
375      "DEBUG $(this.bundle): Services Autorun Enabled"
376        if => "services_autorun";
377
378      "DEBUG $(this.bundle): Services Autorun Bundles Enabled"
379        if => "services_autorun_bundles";
380
381      "DEBUG $(this.bundle): Services Autorun Inputs Enabled"
382        if => "services_autorun_inputs";
383
384      "DEBUG $(this.bundle): Services Autorun (Bundles & Inputs) Enabled"
385        if => "services_autorun";
386
387      "DEBUG $(this.bundle): adding input='$(inputs)'"
388        if => isvariable("inputs");
389
390      "DEBUG $(this.bundle): adding input='$(found_inputs)'"
391        if => isvariable("found_inputs");
392}
393