diff --git a/roles/sap_ha_pacemaker_cluster/README.md b/roles/sap_ha_pacemaker_cluster/README.md index 6cf0c731a..eb5a60660 100644 --- a/roles/sap_ha_pacemaker_cluster/README.md +++ b/roles/sap_ha_pacemaker_cluster/README.md @@ -427,9 +427,9 @@ sap_ha_pacemaker_cluster_resource_defaults: ### sap_ha_pacemaker_cluster_vip_client_interface - _Type:_ `str` -- _Default:_ `eth0` OS device name of the network interface to use for the Virtual IP configuration.
+When there is only one interface on the system, its name will be used by default.
### sap_ha_pacemaker_cluster_vip_hana_primary_ip_address diff --git a/roles/sap_ha_pacemaker_cluster/defaults/main.yml b/roles/sap_ha_pacemaker_cluster/defaults/main.yml index 9b208d45a..a95e171b8 100644 --- a/roles/sap_ha_pacemaker_cluster/defaults/main.yml +++ b/roles/sap_ha_pacemaker_cluster/defaults/main.yml @@ -98,7 +98,7 @@ sap_ha_pacemaker_cluster_fence_options: ### VIP resource default patterns sap_ha_pacemaker_cluster_vip_resource_agent: "ocf:heartbeat:IPaddr2" -sap_ha_pacemaker_cluster_vip_client_interface: eth0 +sap_ha_pacemaker_cluster_vip_client_interface: '' # Multiple VIP parameters can be defined and will be combined. # See tasks/include_construct_vip_resources.yml diff --git a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml index a2035e47a..5a394c0ae 100644 --- a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml +++ b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml @@ -325,9 +325,9 @@ argument_specs: # type: str sap_ha_pacemaker_cluster_vip_client_interface: - default: eth0 description: - OS device name of the network interface to use for the Virtual IP configuration. + - When there is only one interface on the system, its name will be used by default. required: false type: str diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml index 5217de9e8..98a49b57c 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml @@ -13,5 +13,7 @@ - attrs: - name: ip value: "{{ vip_list_item.value | quote }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - __sap_ha_pacemaker_cluster_vip_resource_id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) diff --git a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml index ab3e1bb74..f132a6738 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml @@ -7,6 +7,24 @@ ansible.builtin.setup: gather_subset: hardware,interfaces +# Multi-NIC: +# Find out if there is more than one interface present, this will +# be used for determining the target NIC for VIP configurations. +# Assumption: The local loopback "lo" is always in the list. +- name: "SAP HA Prepare Pacemaker - Set multi-NIC when more than one interface is found" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_nic_multi_bool: true + when: + - ansible_interfaces | length > 2 + +- name: "SAP HA Prepare Pacemaker - Set interface name when only one interface is present" + ansible.builtin.set_fact: + sap_ha_pacemaker_cluster_vip_client_interface: "{{ ansible_default_ipv4.interface }}" + when: + - not __sap_ha_pacemaker_cluster_nic_multi_bool + - sap_ha_pacemaker_cluster_vip_client_interface == '' + + # Include vars files based on the environment. # Respect order for potential variable precedence. - name: "SAP HA Prepare Pacemaker - Include environment specific variables" diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml index 7cec51de1..c34cfac8f 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml @@ -12,6 +12,8 @@ - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml index da995eae2..97b662d67 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml @@ -12,6 +12,8 @@ - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml index 34982f29b..244532aeb 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml @@ -12,6 +12,8 @@ - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml index da995eae2..97b662d67 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml @@ -12,6 +12,8 @@ - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or diff --git a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml index 2ae0ed659..6d77a1c67 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml @@ -1,30 +1,92 @@ --- # The SAP ID must follow a strict format and not use reserved special values -# TODO: This check may be better placed in a SAP role earlier in the chain... -- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP HANA)" +- name: "SAP HA Prepare Pacemaker - (SAP HANA) Validate SAP System ID" ansible.builtin.assert: that: - sap_ha_pacemaker_cluster_hana_sid | length == 3 - sap_ha_pacemaker_cluster_hana_sid not in __sap_sid_prohibited + fail_msg: | + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires 'sap_ha_pacemaker_cluster_hana_sid' to be defined! when: - - "'hana' in sap_ha_pacemaker_cluster_host_type" - - sap_ha_pacemaker_cluster_hana_sid is defined - - sap_ha_pacemaker_cluster_hana_sid | length > 0 + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 -- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP Netweaver)" +- name: "SAP HA Prepare Pacemaker - (SAP NetWeaver) Validate SAP System ID" ansible.builtin.assert: that: - sap_ha_pacemaker_cluster_netweaver_sid | length == 3 - sap_ha_pacemaker_cluster_netweaver_sid not in __sap_sid_prohibited + fail_msg: | + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires 'sap_ha_pacemaker_cluster_netweaver_sid' to be defined! when: - - "'nwas' in sap_ha_pacemaker_cluster_host_type" - - sap_ha_pacemaker_cluster_netweaver_sid is defined - - sap_ha_pacemaker_cluster_netweaver_sid | length > 0 + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas') | length > 0 -- name: "SAP HA Prepare Pacemaker - Verify that a SID is defined" +# NIC definition validation +- name: "SAP HA Prepare Pacemaker - Verify that a custom NIC name is defined when multiple NICs exist" ansible.builtin.assert: that: - - sap_ha_pacemaker_cluster_hana_sid is defined - or sap_ha_pacemaker_cluster_netweaver_sid is defined - - sap_ha_pacemaker_cluster_hana_sid | length > 0 - or sap_ha_pacemaker_cluster_netweaver_sid | length > 0 + - sap_ha_pacemaker_cluster_vip_client_interface is defined + - sap_ha_pacemaker_cluster_vip_client_interface | length > 0 + fail_msg: + Multiple interfaces are found on the system. + + {{ ansible_interfaces | to_nice_yaml }} + + In this case 'sap_ha_pacemaker_cluster_vip_client_interface' must be defined. + when: + - ansible_interfaces | length > 2 + +- name: "SAP HA Prepare Pacemaker - Verify that the custom NIC name exists" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_client_interface in ansible_interfaces + fail_msg: "The interface '{{ sap_ha_pacemaker_cluster_vip_client_interface }}' does not exist on this system!" + when: + - sap_ha_pacemaker_cluster_vip_client_interface | length > 0 + +# VIP definition validation +- name: "SAP HA Prepare Pacemaker - (HANA primary) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address is defined + - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_hana_primary_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver ASCS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address is defined + - sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver ERS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address is defined + - sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs_ers') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver PAS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address is defined + - sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver AAS) Verify that the ERS VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address is defined + - sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas_aas') | length > 0 diff --git a/roles/sap_ha_pacemaker_cluster/vars/main.yml b/roles/sap_ha_pacemaker_cluster/vars/main.yml index c96a08fbf..27b93aee8 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/main.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/main.yml @@ -27,37 +27,14 @@ __sap_ha_pacemaker_cluster_required_facts: # - virtualization_role # subset: virtual # - virtualization_type # subset: virtual +# By default assume non-multi-NIC configuration. +# This is automatically adjusted during preparation tasks. +__sap_ha_pacemaker_cluster_nic_multi_bool: false + # Define empty parameters to avoid undefined input variables. # The arguments_spec check complains. # The actual values must be empty, they are set by various tasks! -__sap_ha_pacemaker_cluster_hana_primary_synonyms: - - primary - - hana_primary - - promoted - - rw - -__sap_ha_pacemaker_cluster_hana_secondary_synonyms: - - secondary - - hana_secondary - - unpromoted - - ro - -__sap_ha_pacemaker_cluster_nwas_ascs_synonyms: - - ascs - - nwas_ascs - - nwas_abap_ascs - -__sap_ha_pacemaker_cluster_nwas_ers_synonyms: - - ers - - nwas_ers - - nwas_abap_ers - -__sap_ha_pacemaker_cluster_nwas_pas_synonyms: - - pas - - nwas_pas - - nwas_abap_pas - # (cloud) platform helper variable - leave empty for default = not cloud __sap_ha_pacemaker_cluster_platform: '' __sap_ha_pacemaker_cluster_supported_platforms: