From aaa2b9af3fca4ce77309905da575d59ee3e4c2a4 Mon Sep 17 00:00:00 2001 From: fracappa Date: Thu, 18 Jun 2026 10:51:25 +0200 Subject: [PATCH 1/2] feat: add macAddress as alternative identifier for fencing credentials Introduce FENCING_CREDENTIALS_IDENTIFIER env var to control whether fencing credentials identify nodes by hostname (default) or macAddress. --- agent/05_agent_configure.sh | 5 +++++ .../install-config_baremetal_yaml.j2 | 17 +++++++++------ agent/roles/manifests/vars/main.yml | 2 ++ common.sh | 3 +++ config_example.sh | 8 +++++++ utils.sh | 21 ++++++++++++------- 6 files changed, 42 insertions(+), 14 deletions(-) diff --git a/agent/05_agent_configure.sh b/agent/05_agent_configure.sh index c321eda85..db2c130be 100755 --- a/agent/05_agent_configure.sh +++ b/agent/05_agent_configure.sh @@ -130,6 +130,9 @@ function configure_node() { AGENT_NODES_IPSV6+=("$ipv6") fi AGENT_NODES_MACS+=("$node_mac") + if [[ "$node_type" == "master" ]]; then + AGENT_MASTER_MACS+=("$node_mac") + fi if [[ ! -z "${BOND_PRIMARY_INTERFACE:-}" ]]; then # For a bond, a random mac is added for the 2nd interface AGENT_NODES_MACS+=("$(sudo virsh domiflist "${cluster_name}" | grep "${BAREMETAL_NETWORK_NAME}" | grep -v "${node_mac}" | awk '{print $5}')") @@ -316,6 +319,8 @@ function generate_cluster_manifests() { master_hostnames=$(printf '%s,' "${AGENT_MASTER_HOSTNAMES[@]}") export AGENT_MASTER_HOSTNAMES_STR=${master_hostnames::-1} + master_macs=$(printf '%s,' "${AGENT_MASTER_MACS[@]}") + export AGENT_MASTER_MACS_STR=${master_macs::-1} master_bmc_usernames=$(printf '%s,' "${AGENT_MASTER_BMC_USERNAMES[@]}") export AGENT_MASTER_BMC_USERNAMES_STR=${master_bmc_usernames::-1} master_bmc_passwords=$(printf '%s,' "${AGENT_MASTER_BMC_PASSWORDS[@]}") diff --git a/agent/roles/manifests/templates/install-config_baremetal_yaml.j2 b/agent/roles/manifests/templates/install-config_baremetal_yaml.j2 index 8d9f9dc9f..ba0c3f94d 100644 --- a/agent/roles/manifests/templates/install-config_baremetal_yaml.j2 +++ b/agent/roles/manifests/templates/install-config_baremetal_yaml.j2 @@ -37,18 +37,23 @@ controlPlane: replicas: {{ num_masters }} {% if enable_two_node_fencing %} {% set master_hostnames = agent_master_hostnames.split(',') %} +{% set master_macs = agent_master_macs.split(',') %} {% set master_bmc_addresses = agent_master_bmc_addresses.split(',') %} {% set master_bmc_usernames = agent_master_bmc_usernames.split(',') %} {% set master_bmc_passwords = agent_master_bmc_passwords.split(',') %} {% set master_bmc_verify_cas = agent_master_bmc_verify_cas.split(',') %} fencing: credentials: -{% for hostname in master_hostnames %} - - hostname: {{hostname}} - address: {{ master_bmc_addresses[loop.index0] }} - username: {{ master_bmc_usernames[loop.index0] }} - password: {{ master_bmc_passwords[loop.index0] }} - certificateVerification: {{ 'Disabled' if bmc_verify_cas[loop.index0] == "False" else 'Enabled' }} +{% for i in range(master_hostnames | length) %} +{% if fencing_credential_identifier == "macAddress" %} + - macAddress: {{ master_macs[i] }} +{% else %} + - hostname: {{ master_hostnames[i] }} +{% endif %} + address: {{ master_bmc_addresses[i] }} + username: {{ master_bmc_usernames[i] }} + password: {{ master_bmc_passwords[i] }} + certificateVerification: {{ 'Disabled' if bmc_verify_cas[i] == "False" else 'Enabled' }} {% endfor %} {% endif %} fips: {{ fips_mode }} diff --git a/agent/roles/manifests/vars/main.yml b/agent/roles/manifests/vars/main.yml index cdeef1fb7..c2f1fd87a 100644 --- a/agent/roles/manifests/vars/main.yml +++ b/agent/roles/manifests/vars/main.yml @@ -31,6 +31,7 @@ cluster_subnet_v4: "{{ lookup('env', 'CLUSTER_SUBNET_V4') }}" cluster_subnet_v6: "{{ lookup('env', 'CLUSTER_SUBNET_V6') }}" enable_local_registry: "{{ lookup('env', 'ENABLE_LOCAL_REGISTRY') != '' }}" enable_two_node_fencing: "{{ lookup('env', 'ENABLE_TWO_NODE_FENCING', default='') == 'true' }}" +fencing_credential_identifier: "{{ lookup('env', 'FENCING_CREDENTIAL_IDENTIFIER', default='hostname') }}" external_subnet_v4: "{{ lookup('env', 'EXTERNAL_SUBNET_V4') }}" external_subnet_v6: "{{ lookup('env', 'EXTERNAL_SUBNET_V6') }}" external_subnet_v4_prefixlen: "{{ lookup('env', 'EXTERNAL_SUBNET_V4') | ansible.utils.ipaddr('prefix') }}" @@ -73,6 +74,7 @@ service_subnet_v4: "{{ lookup('env', 'SERVICE_SUBNET_V4') }}" service_subnet_v6: "{{ lookup('env', 'SERVICE_SUBNET_V6') }}" version: "{{ lookup('env', 'VERSION') }}" agent_master_hostnames: "{{ lookup('env', 'AGENT_MASTER_HOSTNAMES_STR') }}" +agent_master_macs: "{{ lookup('env', 'AGENT_MASTER_MACS_STR') }}" agent_master_bmc_addresses: "{{ lookup('env', 'AGENT_MASTER_BMC_ADDRESSES_STR') }}" agent_master_bmc_passwords: "{{ lookup('env', 'AGENT_MASTER_BMC_PASSWORDS_STR') }}" agent_master_bmc_usernames: "{{ lookup('env', 'AGENT_MASTER_BMC_USERNAMES_STR') }}" diff --git a/common.sh b/common.sh index c70b8d685..c054d6ce8 100644 --- a/common.sh +++ b/common.sh @@ -411,6 +411,9 @@ if [[ -z ${AGENT_E2E_TEST_SCENARIO:-} ]] && [[ ${NUM_ARBITERS} -eq 0 ]] && [[ ${ export ENABLE_TWO_NODE_FENCING="true" fi +# Controls whether fencing credentials use "hostname" or "macAddress" to identify nodes +export FENCING_CREDENTIAL_IDENTIFIER=${FENCING_CREDENTIAL_IDENTIFIER:-hostname} + # Only redfish BMC driver is supported for two node fencing if [[ "${BMC_DRIVER}" != "redfish" ]] && [[ "${ENABLE_TWO_NODE_FENCING:-}" == "true" ]]; then printf "Only redfish BMC driver is supported for Two Node Fencing deployments: BMC_DRIVER=%s, ENABLE_TWO_NODE_FENCING=%s" "${BMC_DRIVER}" "${ENABLE_TWO_NODE_FENCING}" diff --git a/config_example.sh b/config_example.sh index a184c5b53..e7bc7596d 100755 --- a/config_example.sh +++ b/config_example.sh @@ -593,6 +593,14 @@ set -x #export ARBITER_DISK=50 #export ARBITER_VCPU=2 +# FENCING_CREDENTIAL_IDENTIFIER - +# Controls the identifier used in fencing credentials for Two Node Fencing. +# Set to "hostname" to identify nodes by hostname (default), or "macAddress" +# to identify nodes by their boot MAC address. +# Default: "hostname" +# +#export FENCING_CREDENTIAL_IDENTIFIER=hostname + # WORKER_HOSTNAME_FORMAT - # Set a custom hostname format for workers. This is a format string that should # include one %d field, which will be replaced with the number of the node. diff --git a/utils.sh b/utils.sh index c1c0bd41c..08b7d51b9 100755 --- a/utils.sh +++ b/utils.sh @@ -354,19 +354,24 @@ function node_map_to_install_config_fencing_credentials() { credentials: EOF for ((idx=0; idx < NUM_MASTERS ; idx++)); do - # shellcheck disable=SC2059 - hostname="$(printf "$MASTER_HOSTNAME_FORMAT" ${idx})" - # IP V6 and DualStack will force FQDN hostname for the VMs, we need to update - # this here to correctly set the hostname for the fencing credentials. - if [[ $IP_STACK != 'v4' ]]; then - hostname="${hostname}.${CLUSTER_DOMAIN}" - fi username=$(node_val ${idx} "driver_info.username") password=$(node_val ${idx} "driver_info.password") address=$(node_val ${idx} "driver_info.address") + if [[ "${FENCING_CREDENTIAL_IDENTIFIER}" == "macAddress" ]]; then + identifier_key="macAddress" + identifier_value=$(node_val ${idx} "ports[0].address") + else + # shellcheck disable=SC2059 + identifier_value="$(printf "$MASTER_HOSTNAME_FORMAT" ${idx})" + if [[ $IP_STACK != 'v4' ]]; then + identifier_value="${identifier_value}.${CLUSTER_DOMAIN}" + fi + identifier_key="hostname" + fi + cat < Date: Wed, 24 Jun 2026 11:51:53 +0200 Subject: [PATCH 2/2] debug: add env vars debug logs --- agent/05_agent_configure.sh | 3 +++ agent/roles/manifests/tasks/install-config.yml | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/agent/05_agent_configure.sh b/agent/05_agent_configure.sh index db2c130be..d16786793 100755 --- a/agent/05_agent_configure.sh +++ b/agent/05_agent_configure.sh @@ -385,6 +385,9 @@ function generate_cluster_manifests() { export AGENT_ROOT_DEVICE_HINTS=${ISCSI_DEVICE_NAME} fi + echo "DEBUG: FENCING_CREDENTIAL_IDENTIFIER=${FENCING_CREDENTIAL_IDENTIFIER:-NOT_SET}" + echo "DEBUG: AGENT_MASTER_MACS_STR=${AGENT_MASTER_MACS_STR:-NOT_SET}" + # Create manifests ansible-playbook -vvv \ -e install_path="${SCRIPTDIR}/${INSTALL_CONFIG_PATH}" \ diff --git a/agent/roles/manifests/tasks/install-config.yml b/agent/roles/manifests/tasks/install-config.yml index 019a324e3..75a632e84 100644 --- a/agent/roles/manifests/tasks/install-config.yml +++ b/agent/roles/manifests/tasks/install-config.yml @@ -9,6 +9,14 @@ dest: "{{ install_path }}/install-config.yaml" when: platform_type != "baremetal" and platform_type != "vsphere" +- name: DEBUG fencing vars + debug: + msg: > + fencing_credential_identifier={{ fencing_credential_identifier }} + agent_master_macs={{ agent_master_macs }} + enable_two_node_fencing={{ enable_two_node_fencing }} + when: platform_type == "baremetal" + - name: write the install-config.yaml template: src: "templates/install-config_baremetal_yaml.j2"