diff --git a/README.md b/README.md index bb96ca2c..ca67147a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,42 @@ An Ansible role for managing High Availability Clustering. boolean, default: `true` -RHEL and CentOS only, enable repositories contaning needed packages +RHEL and CentOS only, enable repositories containing needed packages + +#### `ha_cluster_manage_firewall` + +boolean, default: false + +Manage the `firewall high-availability service` as well as the `fence-virt port`. +When `ha_cluster_manage_firewall` is `true`, the `firewall high-availability +service` and `fence-virt port` are enabled. +When `ha_cluster_manage_firewall` is `false`, the `ha_cluster role` does not +manage the firewall. + +NOTE: `ha_cluster_manage_firewall` is limited to *adding* ports. +It cannot be used for *removing* ports. +If you want to remove ports, you will need to use the firewall system +role directly. + +#### `ha_cluster_manage_selinux` + +boolean, default: false + +Manage the ports belonging to the `firewall high-availability service` using +the selinux role. +When `ha_cluster_manage_selinux` is `true`, the ports belonging to the +`firewall high-availability service` are associated with the selinux port type +`cluster_port_t`. +When `ha_cluster_manage_selinux` is `false`, the `ha_cluster role` does not +manage the selinux. + +NOTE: The firewall configuration is prerequisite for managing selinux. If the +firewall is not installed, managing selinux policy is skipped. + +NOTE: `ha_cluster_manage_selinux` is limited to *adding* policy. +It cannot be used for *removing* policy. +If you want to remove policy, you will need to use the selinux system +role directly. #### `ha_cluster_cluster_present` @@ -58,7 +93,7 @@ automatically by the role, for example custom resource agents. It is possible to specify fence agents here as well. However, `ha_cluster_fence_agent_packages` is preferred for that, so that its default -value is overriden. +value is overridden. #### `ha_cluster_hacluster_password` @@ -870,7 +905,7 @@ all: #### SBD watchdog and devices When using SBD, you may optionally configure watchdog and SBD devices for each -node in inventory. Even though all SBD devices must be shared to and accesible +node in inventory. Even though all SBD devices must be shared to and accessible from all nodes, each node may use different names for the devices. Watchdog may be different for each node as well. See also [SBD variables](#ha_cluster_sbd_enabled). diff --git a/defaults/main.yml b/defaults/main.yml index 1ac4caee..359c6e7f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -50,3 +50,11 @@ ha_cluster_constraints_location: [] ha_cluster_constraints_colocation: [] ha_cluster_constraints_order: [] ha_cluster_constraints_ticket: [] + +# If true, manage the high-availability service and the fence-virt port +# using the firewall role. +ha_cluster_manage_firewall: false + +# If true, manage the ports belonging to the high-availability service +# and the fence-virt using the selinux role. +ha_cluster_manage_selinux: false diff --git a/meta/collection-requirements.yml b/meta/collection-requirements.yml new file mode 100644 index 00000000..6da97402 --- /dev/null +++ b/meta/collection-requirements.yml @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: MIT +collections: + - fedora.linux_system_roles diff --git a/tasks/firewall.yml b/tasks/firewall.yml index 8649f71f..a444f5d7 100644 --- a/tasks/firewall.yml +++ b/tasks/firewall.yml @@ -1,70 +1,18 @@ # SPDX-License-Identifier: MIT --- -- name: Get services status - detect firewall - service_facts: - -- name: Configure firewalld - block: - - name: Enable service 'high-availability' in firewalld - command: firewall-cmd --add-service high-availability - when: ansible_facts.services['firewalld.service'].state == 'running' - register: __ha_cluster_firewall_cmd - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - - - name: Enable service 'high-availability' in firewalld permanent config - command: firewall-cmd --permanent --add-service high-availability - register: __ha_cluster_firewall_cmd - when: ansible_facts.services['firewalld.service'].state == 'running' - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - - - name: Enable service 'high-availability' in firewalld offline config - command: firewall-offline-cmd --add-service high-availability - register: __ha_cluster_firewall_cmd - when: ansible_facts.services['firewalld.service'].state != 'running' - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - - - name: Enable fence-virt port in firewalld - all options - when: - - ansible_architecture == 'x86_64' - - ( - 'fence-virt' in ha_cluster_fence_agent_packages - or - 'fence-virt' in ha_cluster_extra_packages - or - 'fence-agents-all' in ha_cluster_fence_agent_packages - or - 'fence-agents-all' in ha_cluster_extra_packages - ) - block: - - name: Enable fence-virt port in firewalld - command: firewall-cmd --add-port 1229/tcp - when: ansible_facts.services['firewalld.service'].state == 'running' - register: __ha_cluster_firewall_cmd - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - - - name: Enable fence-virt port in firewalld permanent config - command: firewall-cmd --permanent --add-port 1229/tcp - when: ansible_facts.services['firewalld.service'].state == 'running' - register: __ha_cluster_firewall_cmd - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - - - name: Enable fence-virt port in firewalld offline config - command: firewall-offline-cmd --add-port 1229/tcp - when: ansible_facts.services['firewalld.service'].state != 'running' - register: __ha_cluster_firewall_cmd - failed_when: - - __ha_cluster_firewall_cmd.rc != 0 - - __ha_cluster_firewall_cmd.rc != 11 # already enabled - +- name: Ensure the service and the ports status with the firewall role + include_role: + name: fedora.linux_system_roles.firewall + vars: + __arch: "{{ ansible_facts['architecture'] }}" + __use_fence_fw_port: "{{ __arch == 'x86_64' and + ('fence-virt' in ha_cluster_fence_agent_packages + or 'fence-virt' in ha_cluster_extra_packages + or 'fence-agents-all' in ha_cluster_fence_agent_packages + or 'fence-agents-all' in ha_cluster_extra_packages) }}" + __fence_fw_port: "{{ [{'port': '1229/tcp', 'state': 'enabled'}] + if __use_fence_fw_port else [] }}" + __ha_fw_service: [{'service': 'high-availability', 'state': 'enabled' }] + firewall: "{{ __ha_fw_service + __fence_fw_port }}" when: - - '"firewalld.service" in ansible_facts.services' + - ha_cluster_manage_firewall | bool diff --git a/tasks/main.yml b/tasks/main.yml index ec4886f1..fffbd5e5 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -14,6 +14,9 @@ - name: Configure firewall include_tasks: firewall.yml + - name: Configure selinux + include_tasks: selinux.yml + - name: Configure pcs / pcsd include_tasks: pcs-configure-pcs-pcsd.yml diff --git a/tasks/selinux.yml b/tasks/selinux.yml new file mode 100644 index 00000000..be5be0b8 --- /dev/null +++ b/tasks/selinux.yml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: MIT +--- +- name: Populate service facts + service_facts: + +- block: + - name: Set the fence-virt/fence-agents port to _ha_cluster_selinux + set_fact: + _ha_cluster_selinux: + - {'ports': '1229', 'proto': 'tcp', 'setype': 'cluster_port_t', + 'state': 'present', 'local': true} + when: + - ( + 'fence-virt' in ha_cluster_fence_agent_packages + or + 'fence-virt' in ha_cluster_extra_packages + or + 'fence-agents-all' in ha_cluster_fence_agent_packages + or + 'fence-agents-all' in ha_cluster_extra_packages + ) + + - name: Get associated selinux ports + shell: |- + set -euo pipefail + firewall-cmd --info-service=high-availability | \ + egrep " +ports: +" | sed -e "s/ *ports: //" + register: __ports + changed_when: false + + - name: Add the high-availability service ports to _ha_cluster_selinux + set_fact: + _ha_cluster_selinux: "{{ _ha_cluster_selinux | d([]) + + [{'ports': _pair[0], 'proto': _pair[1], 'setype': 'cluster_port_t', + 'state': 'present', 'local': true}] }}" + vars: + _pair: "{{ item.split('/') }}" + loop: "{{ __ports.stdout.split(' ') }}" + + - name: Ensure the service and the ports status with the selinux role + include_role: + name: fedora.linux_system_roles.selinux + vars: + selinux_ports: "{{ _ha_cluster_selinux }}" + when: + - '"firewalld.service" in ansible_facts.services' + - ansible_facts.services["firewalld.service"]["state"] == "running" + - ha_cluster_manage_selinux | bool diff --git a/tests/tasks/check_firewall_selinux.yml b/tests/tasks/check_firewall_selinux.yml new file mode 100644 index 00000000..a26c1e21 --- /dev/null +++ b/tests/tasks/check_firewall_selinux.yml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: MIT +--- +- block: + - name: Check firewall service status + command: firewall-cmd --list-services + register: _result + failed_when: "'high-availability' not in _result.stdout" + changed_when: false + + - name: Check firewall port status + command: firewall-cmd --list-ports + register: _result + failed_when: "'1229/tcp' not in _result.stdout" + changed_when: false + when: ha_cluster_manage_firewall | bool + +- block: + - name: Get associated selinux ports + shell: |- + set -euo pipefail + firewall-cmd --info-service=high-availability | \ + egrep " +ports: +" | sed -e "s/ *ports: //" + register: __ports + changed_when: false + + - name: Check associated selinux ports + shell: |- + set -euo pipefail + sudo semanage port --list | grep cluster_port_t | \ + grep "{{ _pair[0] }}" | grep "{{ _pair[1] }}" + vars: + _pair: "{{ item.split('/') }}" + loop: "{{ __ports.stdout.split(' ') }}" + changed_when: false + when: + - '"firewalld.service" in ansible_facts.services' + - ansible_facts.services["firewalld.service"]["state"] == "running" + - ha_cluster_manage_selinux | bool diff --git a/tests/tests_cib_constraints_create.yml b/tests/tests_cib_constraints_create.yml index f1cf6eaf..8e4ac3eb 100644 --- a/tests/tests_cib_constraints_create.yml +++ b/tests/tests_cib_constraints_create.yml @@ -381,6 +381,8 @@ options: - name: loss-policy value: fence + # test to set true to manage selinux to see it's ignored. + ha_cluster_manage_selinux: true tasks: - block: @@ -392,6 +394,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster versions of cluster components include_tasks: tasks/fetch_versions.yml @@ -647,6 +650,9 @@ - ' set d1 (id:ticket_set_d1_set) setoptions ticket=ticket-set1 (id:ticket_set_d1)' - ' set d1 d2 (id:ct-set_set) set d3 d4 require-all=true sequential=false (id:ct-set_set-1) setoptions loss-policy=fence ticket=ticket-set1 (id:ct-set)' + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + # yamllint enable rule:line-length tags: tests::verify diff --git a/tests/tests_cib_properties_empty.yml b/tests/tests_cib_properties_empty.yml index 74296b6b..6856ace7 100644 --- a/tests/tests_cib_properties_empty.yml +++ b/tests/tests_cib_properties_empty.yml @@ -7,6 +7,8 @@ ha_cluster_cluster_name: test-cluster ha_cluster_cluster_properties: - attrs: + # test to set true to manage firewall only + ha_cluster_manage_firewall: true tasks: - block: @@ -18,6 +20,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster properties configuration from the cluster command: @@ -29,4 +32,7 @@ debug: var: __test_pcs_property_config + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cib_properties_one_set.yml b/tests/tests_cib_properties_one_set.yml index ed71c9ac..ee2ceb16 100644 --- a/tests/tests_cib_properties_one_set.yml +++ b/tests/tests_cib_properties_one_set.yml @@ -11,6 +11,8 @@ value: 'true' - name: no-quorum-policy value: stop + ha_cluster_manage_firewall: true + ha_cluster_manage_selinux: true tasks: - block: - name: Set up test environment @@ -21,6 +23,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster properties configuration from the cluster command: @@ -42,4 +45,7 @@ 'stonith-enabled: true' in __test_pcs_property_config.stdout_lines | map('trim') + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cib_resources_create.yml b/tests/tests_cib_resources_create.yml index 7899e6a9..ee687e47 100644 --- a/tests/tests_cib_resources_create.yml +++ b/tests/tests_cib_resources_create.yml @@ -267,6 +267,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster versions of cluster components include_tasks: tasks/fetch_versions.yml @@ -3316,6 +3317,9 @@ ] } ' + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + # yamllint enable rule:line-length tags: tests::verify diff --git a/tests/tests_cluster_advanced_knet_full.yml b/tests/tests_cluster_advanced_knet_full.yml index 2868be86..9dc3650e 100644 --- a/tests/tests_cluster_advanced_knet_full.yml +++ b/tests/tests_cluster_advanced_knet_full.yml @@ -67,6 +67,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster versions of cluster components include_tasks: tasks/fetch_versions.yml @@ -114,6 +115,9 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + always: - name: Unset node addresses variable set_fact: diff --git a/tests/tests_cluster_advanced_knet_implicit.yml b/tests/tests_cluster_advanced_knet_implicit.yml index b94bf453..ee2b9320 100644 --- a/tests/tests_cluster_advanced_knet_implicit.yml +++ b/tests/tests_cluster_advanced_knet_implicit.yml @@ -22,6 +22,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster versions of cluster components include_tasks: tasks/fetch_versions.yml @@ -55,4 +56,7 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cluster_advanced_udp_full.yml b/tests/tests_cluster_advanced_udp_full.yml index f1e66184..a421d62f 100644 --- a/tests/tests_cluster_advanced_udp_full.yml +++ b/tests/tests_cluster_advanced_udp_full.yml @@ -41,6 +41,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch cluster versions of cluster components include_tasks: tasks/fetch_versions.yml @@ -80,4 +81,7 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cluster_basic.yml b/tests/tests_cluster_basic.yml index 04cd3a08..309b4f79 100644 --- a/tests/tests_cluster_basic.yml +++ b/tests/tests_cluster_basic.yml @@ -27,6 +27,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Get services status service_facts: @@ -105,4 +106,7 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cluster_basic_custom_fence_agents.yml b/tests/tests_cluster_basic_custom_fence_agents.yml index 6e39b3de..84f0d11e 100644 --- a/tests/tests_cluster_basic_custom_fence_agents.yml +++ b/tests/tests_cluster_basic_custom_fence_agents.yml @@ -23,6 +23,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Get packages status package_facts: diff --git a/tests/tests_cluster_basic_custom_packages.yml b/tests/tests_cluster_basic_custom_packages.yml index 6d91303a..91d3ce75 100644 --- a/tests/tests_cluster_basic_custom_packages.yml +++ b/tests/tests_cluster_basic_custom_packages.yml @@ -24,6 +24,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Get packages status package_facts: diff --git a/tests/tests_cluster_basic_custom_pcsd_tls.yml b/tests/tests_cluster_basic_custom_pcsd_tls.yml index 1eb84448..a63ca2c8 100644 --- a/tests/tests_cluster_basic_custom_pcsd_tls.yml +++ b/tests/tests_cluster_basic_custom_pcsd_tls.yml @@ -43,6 +43,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Stat pcsd TLS certificate stat: @@ -76,6 +77,9 @@ stat_pcsd_key.stat.checksum == stat_pcsd_key_expected.stat.checksum + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify always: diff --git a/tests/tests_cluster_basic_disabled.yml b/tests/tests_cluster_basic_disabled.yml index f3a71ad8..a6b89eea 100644 --- a/tests/tests_cluster_basic_disabled.yml +++ b/tests/tests_cluster_basic_disabled.yml @@ -17,6 +17,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Get services status service_facts: @@ -31,4 +32,7 @@ - name: Assert cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_cluster_basic_existing_psks.yml b/tests/tests_cluster_basic_existing_psks.yml index ff972659..4dde5b67 100644 --- a/tests/tests_cluster_basic_existing_psks.yml +++ b/tests/tests_cluster_basic_existing_psks.yml @@ -124,6 +124,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Stat corosync authkey stat: @@ -207,6 +208,9 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify always: diff --git a/tests/tests_cluster_basic_new_psks.yml b/tests/tests_cluster_basic_new_psks.yml index c9593c08..c8d77b06 100644 --- a/tests/tests_cluster_basic_new_psks.yml +++ b/tests/tests_cluster_basic_new_psks.yml @@ -100,6 +100,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Stat corosync authkey stat: @@ -175,6 +176,9 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify always: diff --git a/tests/tests_cluster_destroy.yml b/tests/tests_cluster_destroy.yml index 0b2141c3..807454e3 100644 --- a/tests/tests_cluster_destroy.yml +++ b/tests/tests_cluster_destroy.yml @@ -15,6 +15,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Stat corosync.conf stat: diff --git a/tests/tests_sbd_all_options.yml b/tests/tests_sbd_all_options.yml index de8f4965..631ebcec 100644 --- a/tests/tests_sbd_all_options.yml +++ b/tests/tests_sbd_all_options.yml @@ -38,6 +38,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Slurp SBD config file slurp: @@ -69,6 +70,9 @@ __test_sbd_config_lines[-1] == 'SBD_OPTS="-n {{ __ha_cluster_node_name }}"' + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + always: - name: Unset SBD devices and watchdogs set_fact: diff --git a/tests/tests_sbd_defaults.yml b/tests/tests_sbd_defaults.yml index 16ec1759..19251a4d 100644 --- a/tests/tests_sbd_defaults.yml +++ b/tests/tests_sbd_defaults.yml @@ -27,6 +27,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Slurp SBD config file slurp: @@ -89,6 +90,9 @@ - name: Check cluster status include_tasks: tasks/assert_cluster_running.yml + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + always: - name: Clean up test environment for SBD include_role: diff --git a/tests/tests_sbd_defaults_disabled.yml b/tests/tests_sbd_defaults_disabled.yml index 714b57ca..8a958911 100644 --- a/tests/tests_sbd_defaults_disabled.yml +++ b/tests/tests_sbd_defaults_disabled.yml @@ -18,6 +18,7 @@ - name: Run HA Cluster role include_role: name: linux-system-roles.ha_cluster + public: true - name: Get services status service_facts: @@ -29,4 +30,7 @@ - ansible_facts.services["pacemaker.service"].status == "disabled" - ansible_facts.services["sbd.service"].status == "disabled" + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + tags: tests::verify diff --git a/tests/tests_sbd_needs_atb_while_atb_enabled.yml b/tests/tests_sbd_needs_atb_while_atb_enabled.yml index 358b327d..746d2d0d 100644 --- a/tests/tests_sbd_needs_atb_while_atb_enabled.yml +++ b/tests/tests_sbd_needs_atb_while_atb_enabled.yml @@ -30,6 +30,7 @@ - name: Run the role include_role: name: linux-system-roles.ha_cluster + public: true - name: Fetch quorum configuration command: @@ -46,6 +47,9 @@ __test_quorum_config.stdout_lines | map('trim') | list }}" + - name: Check firewall and selinux state + include_tasks: tasks/check_firewall_selinux.yml + when: ansible_play_hosts_all | length is even always: - name: Unset SBD devices variable