1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
bundle agent env_classification
# @brief Classify environment
{
vars:
# We use presence of key files to know the hosts environment
"environment_semaphores" slist => { "/etc/prod", "/etc/staging" };
"environment"
string => ifelse( filesexist( @(environment_semaphores) ), "incoherent",
fileexists("/etc/prod"), "production",
fileexists("/etc/staging"), "staging",
"unknown" );
"env_issue_msg"
string => ifelse( strcmp( "incoherent", $(environment) ),
"WARNING: Environment incoherent (multiple environment semaphores)",
strcmp( "unknown", $(environment) ),
"WARNING: Environment unknown (missing environment semaphores)",
"Host environment classified as $(environment)");
# This is to extract the cfengine role ( hub or client )
"cf_role"
string => ifelse( "policy_server", "Policy Server", "Policy Client");
classes:
# We define a class for the selected environment. It's useful for making
# decisions in other policies
"env_$(environment)"
expression => "any",
scope => "namespace";
}
bundle agent env_info
# @brief Relevant environment information
{
vars:
## Based on the environment we define different contacts.
"admin_contact"
slist => { "admin@acme.com", "oncall@acme.com" },
if => strcmp( $(env_classification.environment), "production" );
"admin_contact"
slist => { "dev@acme.com" },
if => strcmp( $(env_classification.environment), "staging" );
"admin_contact"
slist => { "root@localhost" },
if => strcmp( $(env_classification.environment), "unknown" );
## This is to extract the available package updates status
"updates_available"
data => packageupdatesmatching(".*", ".*", ".*", ".*");
"count_updates" int => length("updates_available");
classes:
# We define a class indicating there are updates available, it might be
# useful for various different policies.
"have_updates_available"
expression => isgreaterthan( $(count_updates), 0),
scope => "namespace";
}
bundle agent motd {
vars:
"motd_path" string => "/etc/motd";
# It's considered best practice to prepare a data container holding the
# information you need to render the template instead of relying on
# current datastate()
# First we extract currently defined classes from datastate(), then we
# construct the template data.
"_state" data => datastate(),
if => not( isvariable ( $(this.promiser) ) ); # Limit recursive growth
# and multiple calls to
# datastate() over
# multiple passes.
"template_data"
data => mergedata('{ "fqhost": "$(sys.fqhost)",
"primary_ip": "$(sys.ipv4)",
"cf_version": "$(sys.cf_version)",
"issue_msg": "$(env_classification.env_issue_msg)",
"cf_role": "$(env_classification.cf_role)",
"count_updates": "$(env_info.count_updates)",
"contacts": env_info.admin_contact,
"classes": _state[classes]
}');
files:
"$(motd_path)"
create => "true",
template_method => "inline_mustache",
template_data => @(template_data),
edit_template_string => '# Managed by CFEngine
{{{issue_msg}}}
***
*** Welcome to {{{fqhost}}}
***
* *** * CFEngine Role: {{{cf_role}}}
* *** * CFEngine Version:{{{cf_version}}}
* *** *
* * Host IP: {{{primary_ip}}}
*** {{#classes.have_updates_available}}{{{count_updates}}} package updates available.{{/classes.have_updates_available}}{{^classes.have_updates_available}}No package updates available or status unknown.{{/classes.have_updates_available}}
* *
* *
* *
For support contact:{{#contacts}}
- {{{.}}}{{/contacts}}$(const.n)';
}
bundle agent __main__
{
methods:
"env_classification";
"env_info";
"motd";
}
|