cfe_internal/enterprise/federation/federation.cf
agent bundles
cfengine_enterprise_federation:config
Prototype: cfengine_enterprise_federation:config
Description: Read/parse config JSON, define variables and classes for use later
Implementation:
bundle agent config
{
vars:
enterprise_edition.(policy_server|am_policy_hub)::
"federation_dir" string => "/opt/cfengine/federation";
"bin_dir" string => "$(federation_dir)/bin";
"path" string => "$(federation_dir)/cfapache/federation-config.json";
# TODO: Instrument augments
"dump_interval" -> {"ENT-4806"}
int => "20",
comment => "Dump data on the feeders every 20 minutes";
# TODO: don't hard-code cftransport user
"transport_user" -> { "ENT-4610" } string => "cftransport";
"transport_home"
string => "$(cfengine_enterprise_federation:config.federation_dir)/cftransport";
config_present::
"data" data => readjson( $(path) );
classes:
enterprise_edition.(policy_server|am_policy_hub)::
"config_present"
expression => fileexists( $(path) );
config_present::
"enabled" expression => or(strcmp("on", "$(data[target_state])"),
strcmp("paused", "$(data[target_state])")),
scope => "namespace";
"am_off" expression => strcmp("off", "$(data[target_state])"),
scope => "namespace";
"am_on" expression => strcmp("on", "$(data[target_state])"),
scope => "namespace";
# _stdlib_path_exists_getenforce and paths.getenforce are defined by masterfiles/lib/paths.cf
default:_stdlib_path_exists_getenforce::
"selinux_enabled"
expression => strcmp("Enforcing", execresult("$(paths.getenforce)", useshell)),
scope => "namespace";
vars:
enabled::
"role" string => "$(data[role])";
"remotes" slist => getindices( @(data[remote_hubs]) );
"login" string => ""; # default
"login"
string => "$(data[remote_hubs][$(remotes)][transport][ssh_user])@$(data[remote_hubs][$(remotes)][transport][ssh_host])",
if => and(
# To ensure we are using a remote hub that's actually enabled
strcmp( "on", "$(data[remote_hubs][$(remotes)][target_state])" ),
# To ensure the remote we are pushing to actually needs the data (is a superhub)
strcmp( "superhub", "$(data[remote_hubs][$(remotes)][role])" ));
am_superhub::
# Public keys of enabled pushing feeders need to be trusted (on a superhub)
"pubkey[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][transport][ssh_pubkey])",
if => and( strcmp( "on", "$(data[remote_hubs][$(remotes)][target_state])" ),
strcmp( "feeder", "$(data[remote_hubs][$(remotes)][role])" ),
strcmp( "push_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])"));
am_feeder::
# Public key(s) of enabled pulling superhub(s) need(s) to be trusted (on a feeder)
"pubkey[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][transport][ssh_pubkey])",
if => and( strcmp( "on", "$(data[remote_hubs][$(remotes)][target_state])" ),
strcmp( "superhub", "$(data[remote_hubs][$(remotes)][role])" ),
strcmp( "pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])"));
am_superhub|am_feeder::
"pubkeys" slist => getvalues( pubkey );
"fingerprint[$(data[remote_hubs][$(remotes)][transport][ssh_host])]"
slist => string_split("$(data[remote_hubs][$(remotes)][transport][ssh_fingerprint])", "$(const.n)", "inf"),
# To ensure we are using a remote hub that's enabled
if => strcmp( "on", "$(data[remote_hubs][$(remotes)][target_state])" );
"fingerprints" slist => maparray("$(this.k) $(this.v)", fingerprint);
"feeder[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][hostkey])",
if => strcmp( "feeder", "$(data[remote_hubs][$(remotes)][role])" );
classes:
enabled::
# Knowing if feeder or superhub is based on explicit setting of role in
# path (federation-config.json)
"am_feeder"
expression => strcmp("feeder", "$(data[role])"),
scope => "namespace";
"am_superhub"
expression => strcmp("superhub", "$(data[role])"),
scope => "namespace";
"am_pusher"
and => {strcmp("superhub", "$(data[remote_hubs][$(remotes)][role])"),
strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"),
strcmp("push_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])")},
comment => "Has an enabled remote superhub with push as transport method, should run push transport",
scope => "namespace";
"am_puller"
and => {"am_superhub",
strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"),
strcmp("pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])")},
comment => "Superhub with some enabled remote hub with pull as transport method, should run pull transport",
scope => "namespace";
"am_transporter"
or => {"am_pusher", "am_puller"},
scope => "namespace";
"am_paused"
expression => strcmp("paused", "$(data[target_state])"),
scope => "namespace";
# Note: in order to see these debugs you must either define the default DEBUG class
# or the namespace prefixed class like:
# cf-agent -KI -DDEBUG
# or
# cf-agent -KI -Dcfengine_enterprise_federation:DEBUG_config
reports:
enabled.(default:DEBUG|DEBUG_config)::
"Federation enabled!";
am_superhub.(default:DEBUG|DEBUG_config)::
"I'm a superhub!";
am_feeder.(default:DEBUG|DEBUG_config)::
"I'm a feeder!";
am_pusher.(default:DEBUG|DEBUG_config)::
"I'm pushing dumps!";
am_puller.(default:DEBUG|DEBUG_config)::
"I'm pulling dumps!";
am_transporter.(default:DEBUG|DEBUG_config)::
"I'm a transporter!";
am_paused.(default:DEBUG|DEBUG_config)::
"I'm paused so won't do any import/dump";
}
cfengine_enterprise_federation:semanage_installed
Prototype: cfengine_enterprise_federation:semanage_installed
Description: Install semanage utility if selinux enabled and cfengine_mp_fr_dependencies_auto_install class is defined if not defined then only warn
Implementation:
bundle agent semanage_installed
{
vars:
"semanage_action"
string => ifelse( "default:_stdlib_path_exists_semanage", "fix", "default:cfengine_mp_fr_dependencies_auto_install", "fix", "warn" ),
comment => "We only want to use semanage if it's available, or if we have
indicated it's ok to install it automatically. This variable
is subsequently used by a commands and packages promises to
warn or fix based.";
debian_6|debian_7|debian_8|ubuntu_12|ubuntu_14|ubuntu_16|rhel_5::
"semanage_package" string => "policycoreutils";
debian_9|debian_10|ubuntu_18|redhat_8|centos_8::
"semanage_package" string => "policycoreutils-python-utils";
redhat_6|centos_6|redhat_7|centos_7::
"semanage_package" string => "policycoreutils-python";
packages:
debian|ubuntu::
"$(semanage_package)"
policy => "present",
package_module => default:apt_get,
action => default:policy ( $(semanage_action) );
redhat::
"$(semanage_package)"
policy => "present",
package_module => default:yum,
action => default:policy ( $(semanage_action) );
reports:
default:DEBUG|DEBUG_semanage_installed::
"paths.semanage = $(paths.semanage)";
!default:_stdlib_path_exists_semanage.!default:cfengine_mp_fr_dependencies_auto_install::
"semanage command is not available at $(paths.semanage). Will only install needed package if cfengine_mp_fr_dependencies_auto_install class is defined in augments(def.json) or with --define cf-agent option.";
}
cfengine_enterprise_federation:transport_user
Prototype: cfengine_enterprise_federation:transport_user
Description: Manage transport user and permissions for remote SSH access
Implementation:
bundle agent transport_user
{
vars:
"user"
string => "$(cfengine_enterprise_federation:config.transport_user)";
"home"
string => "$(cfengine_enterprise_federation:config.transport_home)";
"ssh_key_name" string => "id_FR";
"ssh_priv_key" string => "$(home)/.ssh/$(ssh_key_name)";
"ssh_pub_key" string => "$(ssh_priv_key).pub";
"ssh_auth_keys" string => "$(home)/.ssh/authorized_keys";
"ssh_known_hosts" string => "$(home)/.ssh/known_hosts";
"ssh_config" string => "$(home)/.ssh/config";
"create_files"
slist => {
"$(home)/.",
"$(home)/.ssh/.",
"$(home)/source/.", # Dumps from feeders are taken from here
"$(home)/destination/.", # And dropped here on superhub
"$(ssh_auth_keys)",
"$(ssh_known_hosts)",
"$(ssh_config)"
};
classes:
enabled.selinux_enabled::
"incorrect_ssh_context"
expression => not( or(
regcmp(".*[\s:]ssh_home_t[\s:].*",
execresult("ls -Z $(home) | grep .ssh",
useshell)),
regcmp(".*[\s:]ssh_home_t[\s:].*",
execresult("ls -Z $(ssh_auth_keys)",
useshell)),
regcmp(".*[\s:]ssh_home_t[\s:].*",
execresult("ls -Z $(ssh_priv_key)",
useshell)),
regcmp(".*[\s:]ssh_home_t[\s:].*",
execresult("ls -Z $(ssh_pub_key)",
useshell)),
regcmp(".*[\s:]ssh_home_t[\s:].*",
execresult("ls -Z $(ssh_config)",
useshell))));
users:
"$(user)"
policy => "present",
home_dir => "$(home)";
files:
"$(create_files)"
create => "true";
"$(home)/."
depth_search => default:recurse_with_base("inf"),
file_select => default:all,
perms => default:mog( "600", $(user), "root" );
"$(ssh_auth_keys)"
create => "true",
handle => "ssh_auth_keys_configured",
edit_template_string => "}$(const.n)",
template_data => @(cfengine_enterprise_federation:config.pubkeys),
template_method => "inline_mustache";
"$(ssh_known_hosts)"
create => "true",
handle => "ssh_known_hosts_configured",
edit_template_string => "}$(const.n)",
template_data => @(cfengine_enterprise_federation:config.fingerprints),
template_method => "inline_mustache",
if => isvariable("cfengine_enterprise_federation:config.fingerprints");
"$(ssh_config)"
create => "true",
handle => "ssh_config_configured",
edit_line => default:insert_lines("IdentityFile $(ssh_priv_key)");
methods:
selinux_enabled::
"semanage_installed" usebundle => semanage_installed;
commands:
# _stdlib_path_exists_<command> and paths.<command> are defined is masterfiles/lib/paths.cf
selinux_enabled.incorrect_ssh_context.default:_stdlib_path_exists_semanage.default:_stdlib_path_exists_restorecon::
"$(paths.semanage) fcontext -a -t ssh_home_t '$(home)/.ssh(/.*)?'";
"$(paths.restorecon) -R -F $(home)/.ssh/";
any::
# Generate ssh keypair
"/usr/bin/ssh-keygen"
handle => "ssh_keys_configured",
args => "-N '' -f $(ssh_priv_key)",
if => and( isdir( "$(home)/.ssh" ),
not( fileexists( "$(ssh_priv_key)" )));
reports:
selinux_enabled.incorrect_ssh_context.!default:_stdlib_path_exists_semanage::
"need to fix incorrect ssh context for transport user but semanage path in $(sys.libdir)/paths.cf $(paths.semanage) does not resolve";
selinux_enabled.incorrect_ssh_context.!default:_stdlib_path_exists_restorecon)::
"need to fix incorrect ssh context for transport user but restorecon path in $(sys.libdir)/paths.cf $(paths.restorecon) does not resolve";
}
cfengine_enterprise_federation:clean_when_off
Prototype: cfengine_enterprise_federation:clean_when_off
Description: cleanup changes made for federated reporting on a feeder NOTE: a superhub turned off by removing federation-config.json or setting target_state=off will not revert schema changes. federation_manage_files will always run regardless of off or not so as to be prepared for enablement via Mission Portal UI
Implementation:
bundle agent clean_when_off
{
vars:
"user" string => "$(cfengine_enterprise_federation:transport_user.user)";
"home" string => "$(cfengine_enterprise_federation:transport_user.home)";
users:
"$(user)"
policy => "absent";
methods:
"rm_rf_cftransport_home_dir" usebundle => default:rm_rf("$(home)");
classes:
selinux_enabled.default:_stdlib_path_exists_semanage::
"has_cftransport_fcontext" expression => returnszero("$(paths.semanage) fcontext -l | grep $(home)", "useshell");
commands:
# _stdlib_path_exists_<command> and paths.<command> are defined is masterfiles/lib/paths.cf
selinux_enabled.default:_stdlib_path_exists_semanage.has_cftransport_fcontext::
"$(paths.semanage) fcontext -d '$(home)/.ssh(/.*)?'";
}
cfengine_enterprise_federation:federation_manage_files
Prototype: cfengine_enterprise_federation:federation_manage_files
Description: Manage files, directories and permissions in $(cfengine_enterprise_federation:config.federation_dir)
Implementation:
bundle agent federation_manage_files
{
vars:
"transport_user"
string => "$(cfengine_enterprise_federation:config.transport_user)";
"login" data => parsejson('{"login":"$(cfengine_enterprise_federation:config.login)"}');
"feeder_username" data => parsejson('{"feeder_username":"$(cfengine_enterprise_federation:config.transport_user)"}');
"feeder" data => parsejson('{"feeder": "$(sys.key_digest)"}');
"cf_version" data => parsejson('{"cf_version":"$(sys.cf_version)"}');
files:
enterprise_edition.(policy_server|am_policy_hub)::
# Both cfpache and $(transport_user) need permission so adding o+x here
"$(cfengine_enterprise_federation:config.federation_dir)/."
create => "true",
perms => default:mog( "661", "root", "root" );
"$(cfengine_enterprise_federation:config.federation_dir)/cfapache/."
create => "true",
perms => default:mog( "600", "cfapache", "root" );
"$(cfengine_enterprise_federation:config.federation_dir)/cfapache/."
depth_search => default:recurse_with_base("inf"),
file_select => default:all,
perms => default:mog( "600", "cfapache", "root" );
enabled::
"$(cfengine_enterprise_federation:config.bin_dir)/."
create => "true",
perms => default:mog( "660", "root", "$(transport_user)" );
am_superhub::
"$(cfengine_enterprise_federation:config.federation_dir)/superhub/."
create => "true",
perms => default:mog( "770", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/."
create => "true",
perms => default:mog( "600", "root", "root" );
"$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/filters/."
create => "true",
perms => default:mog( "600", "root", "root" );
am_feeder::
"$(cfengine_enterprise_federation:config.federation_dir)/fedhub/."
create => "true",
perms => default:mog( "660", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.federation_dir)/fedhub/dump/."
create => "true",
perms => default:mog( "660", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.federation_dir)/fedhub/transport/."
create => "true",
perms => default:mog( "660", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.federation_dir)/fedhub/dump/filters/."
create => "true",
perms => default:mog( "600", "root", "root" );
am_feeder|am_transporter|am_superhub::
# TODO: Instrument augments
"$(cfengine_enterprise_federation:config.bin_dir)/config.sh"
create => "true",
template_method => "mustache",
edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/config.sh.mustache",
template_data => mergedata(@(login), @(feeder_username), @(feeder), @(cf_version),
parsejson('{"inventory_refresh_cmd": ""}')),
perms => default:mog( "640", "root", "$(transport_user)" );
# TODO: Instrument augments
"$(cfengine_enterprise_federation:config.bin_dir)/log.sh"
create => "true",
template_method => "mustache",
edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/log.sh.mustache",
perms => default:mog( "640", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.bin_dir)/parallel.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/parallel.sh" ),
perms => default:mog( "640", "root", "$(transport_user)" );
"$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh" -> { "ENT-4792"}
create => "true",
edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/psql_wrapper.sh.mustache",
template_method => "mustache",
perms => default:mog( "700", "root", "root" );
am_feeder::
"$(cfengine_enterprise_federation:config.bin_dir)/dump.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/dump.sh" ),
perms => default:mog( "700", "root", "root" );
"$(cfengine_enterprise_federation:config.federation_dir)/fedhub/dump/filters/50-merge_inserts.awk"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/50-merge_inserts.awk" ),
perms => default:mog( "600", "root", "root" );
am_transporter::
"$(cfengine_enterprise_federation:config.bin_dir)/transport.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/transport.sh" ),
perms => default:mog( "500", "$(transport_user)", "root" );
am_puller::
"$(cfengine_enterprise_federation:config.bin_dir)/pull_dumps_from.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/pull_dumps_from.sh" ),
perms => default:mog( "500", "$(transport_user)", "root" );
am_superhub::
"$(cfengine_enterprise_federation:config.bin_dir)/import.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/import.sh" ),
perms => default:mog( "700", "root", "root" );
"$(cfengine_enterprise_federation:config.bin_dir)/import_file.sh"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/import_file.sh" ),
perms => default:mog( "700", "root", "root" );
"$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/filters/10-base_filter.sed"
copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/10-base_filter.sed" ),
perms => default:mog( "600", "root", "root" );
}
cfengine_enterprise_federation:postgres_config
Prototype: cfengine_enterprise_federation:postgres_config
Description: Customize postgres config for superhub
Implementation:
bundle agent postgres_config
{
vars:
am_superhub::
"c[shared_buffers]"
string => "1GB",
comment => "Changing this setting requires restarting the database.";
"c[max_locks_per_transaction]"
string => "4000",
comment => "Changing this setting requires restarting the database.";
"c[log_lock_waits]"
string => "on",
comment => "Changing this setting requires restarting the database.";
files:
am_superhub::
"$(sys.statedir)/pg/data/postgresql.conf"
edit_line => default:set_line_based( "$(this.namespace):$(this.bundle).c",
"=",
"\s*=\s*",
".*",
""),
classes => default:results( "bundle", "postgresql_conf" );
commands:
am_superhub.postgresql_conf_repaired.!systemd::
# smart mode tries to wait for operations to finish and clients to
# disconnect, fast mode terminates open connections gracefully
"$(sys.bindir)/pg_ctl --pgdata $(sys.statedir)/pg/data --log /var/log/postgresql.log --wait --mode smart restart ||
$(sys.bindir)/pg_ctl --pgdata $(sys.statedir)/pg/data --log /var/log/postgresql.log --wait --mode fast restart"
contain => cfpostgres_user;
services:
am_superhub.postgresql_conf_repaired.systemd::
"cf-postgres"
service_method => default:standard_services,
service_policy => "restart";
}
cfengine_enterprise_federation:exported_data
Prototype: cfengine_enterprise_federation:exported_data
Description: Run script to dump pg data on feeder hub
Implementation:
bundle agent exported_data
{
methods:
am_feeder.!am_paused::
"Refresh Inventory"
usebundle => "default:cfe_internal_refresh_inventory_view",
handle => "fr_inventory_refresh",
comment => "Use standard inventory refresh so that we don't run it twice";
commands:
am_feeder.!am_paused::
"/bin/bash"
arglist => {"$(cfengine_enterprise_federation:config.bin_dir)/dump.sh"},
contain => default:in_shell,
depends_on => { "fr_inventory_refresh" },
comment => "Refresh Inventory must be completed before dumping data";
}
cfengine_enterprise_federation:data_transport
Prototype: cfengine_enterprise_federation:data_transport
Description: Run script to transport data from feeder to superhub
Implementation:
bundle agent data_transport
{
vars:
am_puller.!am_paused::
# local copies of the variables to make using them below sane
"remotes" slist => {@(cfengine_enterprise_federation:config.remotes)};
"data" data => @(cfengine_enterprise_federation:config.data);
"enabled_pull_hosts[$(remotes)]"
string => "$(data[remote_hubs][$(remotes)][transport][ssh_host])",
if => and(strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"),
strcmp("pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])"));
"pull_args" -> {"ENT-4499"}
string => join(" ", getvalues(@(enabled_pull_hosts)));
commands:
am_pusher.!am_paused::
"/bin/bash"
arglist => {"$(cfengine_enterprise_federation:config.bin_dir)/transport.sh push"},
contain => contain_transport_user;
am_puller.!am_paused::
"/bin/bash"
arglist => {"$(cfengine_enterprise_federation:config.bin_dir)/transport.sh pull $(pull_args)"},
contain => contain_transport_user;
}
cfengine_enterprise_federation:pre_import_state
Prototype: cfengine_enterprise_federation:pre_import_state
Description: Get the superhub into a state ready for importing dumps from feeders
Implementation:
bundle agent pre_import_state
{
meta:
"comment" string => "We need to stop cf-hub to prevent deadlocks on the PostgreSQL database";
services:
systemd::
"cf-hub"
service_policy => "stop",
service_method => default:standard_services;
processes:
!systemd::
"cf-hub"
process_select => daemon_select, # we want the main process (not its child processes)
signals => {"term"};
}
cfengine_enterprise_federation:imported_data
Prototype: cfengine_enterprise_federation:imported_data
Description: Run script to import dumps on superhub
Implementation:
bundle agent imported_data
{
commands:
"/bin/bash"
arglist => {"$(cfengine_enterprise_federation:config.bin_dir)/import.sh"},
contain => default:in_shell;
}
cfengine_enterprise_federation:post_import_state
Prototype: cfengine_enterprise_federation:post_import_state
Description: Get the superhub into the standard state, after importing dumps from feeders
Implementation:
bundle agent post_import_state
{
services:
systemd::
"cf-hub"
service_policy => "start",
service_method => default:standard_services;
commands:
!systemd::
"/var/cfengine/bin/cf-hub";
}
cfengine_enterprise_federation:superhub_schema
Prototype: cfengine_enterprise_federation:superhub_schema
Description: Run SQL script to ensure schema is migrated to superhub partitioned tables architecture
Implementation:
bundle agent superhub_schema
{
commands:
am_superhub::
"$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh"
arglist => {
"cfdb",
`"select superhub_schema('$(sys.key_digest)');"`,
},
classes => psql_wrapper_exit_codes;
}
cfengine_enterprise_federation:ensure_feeders
Prototype: cfengine_enterprise_federation:ensure_feeders
Description: Run SQL function to ensure that all configured feeder hubs are in __hubs table
Implementation:
bundle agent ensure_feeders
{
vars:
am_superhub::
"feeders" slist => getvalues( "cfengine_enterprise_federation:config.feeder");
"feeders_arg" string => concat( "ARRAY['", join( "', '", feeders ), "']");
commands:
am_superhub::
"$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh"
arglist => {
"cfdb",
`"select ensure_feeders($(feeders_arg));"`
},
classes => psql_wrapper_exit_codes,
if => isgreaterthan(length(feeders), 0);
}
cfengine_enterprise_federation:entry
Prototype: cfengine_enterprise_federation:entry
Description: Conditionally runs all federated reporting bundles
Implementation:
bundle agent entry
{
meta:
(policy_server|am_policy_hub).enterprise_edition::
"tags" -> { "ENT-4383" }
slist => { "enterprise_maintenance" };
classes:
enterprise_edition.(policy_server|am_policy_hub)::
"config_exists"
expression => fileexists("$(cfengine_enterprise_federation:config.federation_dir)/cfapache/federation-config.json");
enterprise_edition.(policy_server|am_policy_hub)::
"config_not_exists"
expression => not(fileexists("$(cfengine_enterprise_federation:config.federation_dir)/cfapache/federation-config.json"));
methods:
config_exists::
"CFEngine Enterprise Federation Configuration"
handle => "config",
usebundle => config;
am_off|config_not_exists::
"CFEngine Enterprise Federation Transport Off"
handle => "clean_when_off",
usebundle => clean_when_off;
enabled.am_on::
"CFEngine Enterprise Federation Transport User"
handle => "transport_user",
usebundle => transport_user;
enterprise_edition.(policy_server|am_policy_hub)::
"federation_manage_files"
handle => "federation_manage_files",
usebundle => federation_manage_files;
enabled.am_on::
"CFEngine Enterprise Federation Postgres Configuration"
handle => "postgres_config",
usebundle => postgres_config;
"CFEngine Enterprise Federation Schema Migration"
handle => "superhub_schema",
depends_on => { "postgres_config" },
usebundle => superhub_schema;
"CFEngine Enterprise Federation Ensure Feeder Hubs in Database"
handle => "ensure_feeders",
depends_on => { "superhub_schema" },
usebundle => ensure_feeders;
"CFEngine Enterprise Federation Feeder Data Transport"
handle => "data_transport",
depends_on => { "transport_user" },
usebundle => data_transport;
"CFEngine Enterprise Federation Feeder Data Export"
usebundle => exported_data,
action => default:if_elapsed($(cfengine_enterprise_federation:config.dump_interval));
"Configuration Status"
usebundle => setup_status;
enabled.am_on.am_superhub.!am_paused::
"CFEngine Enterprise Federation Feeder Data Import Preparations"
handle => "pre_import_state",
depends_on => { "transport_user", "ensure_feeders" },
usebundle => pre_import_state;
"CFEngine Enterprise Federation Feeder Data Import"
handle => "imported_data",
depends_on => { "pre_import_state" },
usebundle => imported_data;
"CFEngine Enterprise Federation Feeder Data Import Cleanups"
handle => "post_import_state",
depends_on => { "imported_data" },
usebundle => post_import_state;
reports:
!enterprise_edition::
"Federated reporting is only available in CFEngine Enterprise.";
enterprise_edition.!(policy_server|am_policy_hub)::
"Federated reporting is only available on the policy server / hub.";
}
cfengine_enterprise_federation:setup_status
Prototype: cfengine_enterprise_federation:setup_status
Implementation:
bundle agent setup_status
{
vars:
"role" string => "$(cfengine_enterprise_federation:config.role)";
"ssh_pub_key"
string => readfile( "$(cfengine_enterprise_federation:transport_user.ssh_pub_key)" ),
if => fileexists( "$(cfengine_enterprise_federation:transport_user.ssh_pub_key)" );
"ssh_server_fingerprint"
# ssh-keyscan is used because it's more reliable/easy than trying to
# parse sshd config to find the file and then readfile():
string => execresult("ssh-keyscan localhost 2>/dev/null | sed 's/localhost //g'", useshell);
classes:
"superhub_setup_status_complete"
expression => "any",
depends_on => {
"config",
"transport_user",
"postgres_config", # We are depending on a deep guard within this bundle
"federation_manage_files",
};
files:
superhub_setup_status_complete::
"$(cfengine_enterprise_federation:config.federation_dir)/cfapache/setup-status.json"
create => "true",
perms => default:mog( "600", "cfapache", "root" ),
template_method => "inline_mustache",
edit_template_string => "$(const.n)",
template_data => '{
"configured": true,
"role": "$(role)",
"hostkey": "$(sys.key_digest)",
"transport_ssh_public_key": "$(ssh_pub_key)",
"transport_ssh_server_fingerprint": "$(ssh_server_fingerprint)",
}',
if => isvariable( ssh_pub_key );
}
main
Prototype: __main__
Description: You can run this policy file from shell without specifying bundle
Implementation:
bundle agent __main__
{
methods:
"entry" usebundle => cfengine_enterprise_federation:entry;
}
file bodies
control
Prototype: control
Implementation:
body file control
{
namespace => "cfengine_enterprise_federation";
}
contain bodies
cfengine_enterprise_federation:cfpostgres_user
Prototype: cfengine_enterprise_federation:cfpostgres_user
Implementation:
body contain cfpostgres_user
{
useshell => "useshell";
exec_owner => "cfpostgres";
exec_group => "cfpostgres";
chdir => "/tmp";
no_output => "false";
}
cfengine_enterprise_federation:contain_transport_user
Prototype: cfengine_enterprise_federation:contain_transport_user
Implementation:
body contain contain_transport_user
{
exec_owner => "$(cfengine_enterprise_federation:config.transport_user)";
exec_group => "$(cfengine_enterprise_federation:config.transport_user)";
chdir => "$(cfengine_enterprise_federation:config.transport_home)";
useshell => "true";
}
process_select bodies
cfengine_enterprise_federation:daemon_select
Prototype: cfengine_enterprise_federation:daemon_select
Description: Select a daemon process (with PPID equal to 1)
Implementation:
body process_select daemon_select
{
ppid => irange(1, 1);
process_result => "ppid";
}
classes bodies
cfengine_enterprise_federation:psql_wrapper_exit_codes
Prototype: cfengine_enterprise_federation:psql_wrapper_exit_codes
Implementation:
body classes psql_wrapper_exit_codes
{
kept_returncodes => { "0" };
repaired_returncodes => { "1" };
failed_returncodes => { "2" };
}
file bodies
cfengine_enterprise_federation:control
Prototype: cfengine_enterprise_federation:control
Implementation:
body file control
{
namespace => "default";
}