1bundle agent ha_update 2{ 3 methods: 4 5 enable_cfengine_enterprise_hub_ha:: 6 7 "Hubs have am_policy_hub marker" 8 usebundle => ha_hubs_have_am_policy_hub_marker, 9 comment => "All hubs should have the am_policy_hub marker. This bundle 10 ensures that standby hubs get this marker even though they are not 11 bootstrapped to themselves"; 12 13 enable_cfengine_enterprise_hub_ha.am_policy_hub:: 14 "share_keys" usebundle => ha_share_hub_keys; 15 "sync_hub_data" usebundle => ha_hub_sync; 16 17 enable_cfengine_enterprise_hub_ha.!am_policy_hub:: 18 "sync_agent_data" usebundle => ha_agent_sync; 19 20 enable_cfengine_enterprise_hub_ha.hub_data_synced:: 21 "manage_keys" usebundle => manage_hub_synced_data; 22 23 enable_cfengine_enterprise_hub_ha.ha_replication_only_node:: 24 "syncronize_master_hub_dat" usebundle => sync_master_hub_dat; 25} 26 27bundle agent ha_hubs_have_am_policy_hub_marker 28# @brief Ensure that all ha hub members have the am_policy_hub state marker 29{ 30 classes: 31 # We know we need the am_policy_hub marker if any of our ips are found in the ha definition 32 "ha_hub_member" expression => iprange( $(ha_def.ips) ); 33 34 files: 35 36 ha_hub_member:: 37 38 "$(sys.statedir)/am_policy_hub" -> { "ENT-3328" } 39 create => "true", 40 comment => "This file is automatically created when bootstrapping to 41 self, but in a clustered environment standby hubs bootstrap to the 42 primary and this marker will not be automatically created."; 43 44} 45 46bundle agent ha_agent_sync 47{ 48 files: 49 "$(sys.workdir)/policy_server.dat" 50 copy_from => ha_update_ha_no_backup_scp("$(ha_def.master_hub_location)", @(update_def.policy_servers)), 51 handle => "ha_cfengine_node_update_master_ip", 52 comment => "Update master hub IP on CFEngine node. This is causing that clients will try 53 to contact active/master hub first."; 54 55 "$(sys.workdir)/ppkeys" 56 copy_from => ha_update_ha_no_backup_scp("$(ha_def.hubs_keys_location)", @(update_def.policy_servers)), 57 file_select => hub_all_keys, 58 depth_search => ha_update_ha_recurse("inf"), 59 handle => "ha_copy_hub_keys_to_nodes", 60 comment => "Download keys of all hubs working in HA cluster and store in client's ppkeys directory. 61 This is important for establishing trusted connection with standby hub(s) in 62 case of failover."; 63} 64 65bundle agent ha_share_hub_keys 66{ 67 files: 68 "$(ha_def.hubs_keys_location)" 69 copy_from => ha_update_no_backup_cp("$(sys.workdir)/ppkeys"), 70 file_select => hubs_keys_select, 71 handle => "ha_copy_hubs_keys", 72 depth_search => ha_update_recurse("1"), 73 comment => "Clients need to be able to download keys of all hubs working in 74 HA cluster. This is needed to establish trusted connection 75 with standby hubs in case of failover. In order to limit possibility 76 of copying wrong keys hub keys are copied to separate directory first 77 and only ppkeys_hubs is accessible by clients."; 78} 79 80bundle agent ha_hub_sync 81{ 82 vars: 83 "exclude_files" slist => {"localhost.priv", "localhost.pub", @(ha_def.hub_shas)}; 84 files: 85 "$(ha_def.ppkeys_staging)" 86 copy_from => ha_update_ha_no_backup_scp("$(sys.workdir)/ppkeys", @(update_def.standby_servers)), 87 file_select => ha_update_ex_list(@(exclude_files)), 88 handle => "ha_copy_client_keys_between_replica_set_servers", 89 depth_search => ha_update_recurse("1"), 90 classes => ha_update_if_repaired("hub_data_synced"), 91 comment => "Distribute all client keys between replica set servers. This is 92 important in case of failover. Once clients keys are synchronized 93 between all hubs working in HA cluster, clients will be able 94 to authenticate and establish connection with all hubs working in HA cluster."; 95} 96 97bundle agent manage_hub_synced_data 98# @brief Manage trust of clients bootstrapped other hubs in cluster 99# 100# Ensures keys collected from other hubs are present in ppkeys so that the 101# agents bootstrapped to other hubs are trusted. 102{ 103 files: 104 105 # Ensure that localhost.pub and localhost.priv are not in the directory of 106 # keys collected from standby hubs 107 108 "$(ha_def.ppkeys_staging)/localhost.*" -> { "ENT-3303" } 109 delete => ha_tidy, 110 handle => "manage_hub_synced_data_ppkeys_staging_localhost_absent", 111 comment => "We don't want localhost related key files from a standby 112 server to end up over-writing the active hubs key. That will 113 cause an identity crisis and trust issues."; 114 115 # Ensure that keys collected from standby hubs are present in this hubs 116 # ppkeys directory so that agents bootstrapped to standby hubs will be 117 # trusted. 118 119 "$(sys.workdir)/ppkeys" 120 copy_from => ha_update_no_backup_cp("$(ha_def.ppkeys_staging)"), 121 file_select => ha_update_plain, 122 depth_search => ha_update_recurse("1"), 123 handle => "ha_copy_staged_client_keys", 124 comment => "Copy staged client keys to ppkeys. First client keys are copied 125 to ppkeys_staging directory and then to ppkeys. Only clients which 126 keys are copied to ppkeys will be able to authenticate and connect 127 to hub."; 128} 129 130bundle agent sync_master_hub_dat 131{ 132 files: 133 "$(ha_def.master_hub_location)" 134 copy_from => ha_update_ha_no_backup_scp("$(ha_def.master_hub_location)", @(update_def.standby_servers)), 135 comment => "Update master hub IP on CFEngine node", 136 handle => "ha_cfengine_hub_update_master_ip"; 137 138} 139 140body file_select hub_all_keys 141{ 142 leaf_name => {".*.pub"}; 143 file_result => "leaf_name"; 144} 145 146body file_select hubs_keys_select 147{ 148 search_size => irange("426", "426"); 149 leaf_name => {escape("root-SHA=$(ha_def.config[$(update_def.standby_servers)][sha]).pub")}; 150 file_result => "leaf_name"; 151} 152 153body copy_from ha_update_ha_no_backup_scp(from,server) 154{ 155 servers => { "$(server)" }; 156 source => "$(from)"; 157 compare => "digest"; 158 copy_backup => "false"; 159 encrypt => "true"; 160} 161 162body depth_search ha_update_ha_recurse(d) 163{ 164 depth => "$(d)"; 165 exclude_dirs => { "\.svn", "\.git", "git-core" }; 166} 167 168body depth_search ha_update_recurse(d) 169{ 170 depth => "$(d)"; 171 xdev => "true"; 172} 173 174body classes ha_update_if_repaired(x) 175{ 176 promise_repaired => { "$(x)" }; 177} 178 179body file_select ha_update_ex_list(names) 180{ 181 leaf_name => { @(names)}; 182 file_result => "!leaf_name"; 183} 184 185body file_select ha_update_plain 186{ 187 file_types => { "plain" }; 188 file_result => "file_types"; 189} 190 191body copy_from ha_update_no_backup_cp(from) 192{ 193 source => "$(from)"; 194 copy_backup => "false"; 195} 196 197body delete ha_tidy 198# @brief Copy of body delete tidy from the standard library 199{ 200 dirlinks => "delete"; 201 rmdirs => "true"; 202} 203