2727requirements:
2828 - pcs-0.10.8 or newer installed on managed nodes
2929 - pcs-0.10.8 or newer for exporting corosync configuration
30+ - python3-firewall for exporting ha_cluster_manage_firewall
31+ - python3-policycoreutils for exporting ha_cluster_manage_selinux
3032 - python 3.6 or newer
3133"""
3234
4951 certain variables may not be exported.
5052 - HORIZONTALLINE
5153 - Following variables are present in the output
54+ - ha_cluster_enable_repos
55+ - ha_cluster_enable_repos_resilient_storage
56+ - ha_cluster_manage_firewall
57+ - ha_cluster_manage_selinux
5258 - ha_cluster_cluster_present
5359 - ha_cluster_start_on_boot
60+ - ha_cluster_install_cloud_agents
61+ - ha_cluster_pcs_permission_list
5462 - ha_cluster_cluster_name
5563 - ha_cluster_transport
5664 - ha_cluster_totem
6472 - HORIZONTALLINE
6573 - Following variables are never present in this module output (consult
6674 the role documentation for impact of the variables missing)
75+ - ha_cluster_fence_agent_packages
76+ - ha_cluster_extra_packages
77+ - ha_cluster_use_latest_packages
78+ - ha_cluster_hacluster_qdevice_password
6779 - ha_cluster_corosync_key_src
6880 - ha_cluster_pacemaker_key_src
6981 - ha_cluster_fence_virt_key_src
82+ - ha_cluster_pcsd_public_key_src
83+ - ha_cluster_pcsd_private_key_src
84+ - ha_cluster_pcsd_certificates
7085 - ha_cluster_regenerate_keys
7186 - HORIZONTALLINE
7287"""
7893# pylint: disable=no-name-in-module
7994from ansible .module_utils .ha_cluster_lsr .info import exporter , loader
8095
96+ try :
97+ # firewall module doesn't provide type hints
98+ from firewall .client import FirewallClient # type:ignore
99+
100+ HAS_FIREWALL = True
101+ except ImportError :
102+ # create the class so it can be replaced by a mock in unit tests
103+ class FirewallClient : # type: ignore
104+ # pylint: disable=missing-class-docstring
105+ # pylint: disable=too-few-public-methods
106+ pass
107+
108+ HAS_FIREWALL = False
109+
110+ try :
111+ # selinux module doesn't provide type hints
112+ from seobject import portRecords as SelinuxPortRecords # type: ignore
113+
114+ HAS_SELINUX = True
115+ except ImportError :
116+ # create the class so it can be replaced by a mock in unit tests
117+ class SelinuxPortRecords : # type: ignore
118+ # pylint: disable=missing-class-docstring
119+ # pylint: disable=too-few-public-methods
120+ pass
121+
122+ HAS_SELINUX = False
123+
81124
82125def get_cmd_runner (module : AnsibleModule ) -> loader .CommandRunner :
83126 """
@@ -94,6 +137,74 @@ def runner(
94137 return runner
95138
96139
140+ def export_os_configuration (module : AnsibleModule ) -> Dict [str , Any ]:
141+ """
142+ Export OS configuration managed by the role
143+ """
144+ result : dict [str , Any ] = dict ()
145+ cmd_runner = get_cmd_runner (module )
146+
147+ if loader .is_rhel_or_clone ():
148+ # The role only enables repos on RHEL and SLES.
149+ dnf_repolist = loader .get_dnf_repolist (cmd_runner )
150+ if dnf_repolist is not None :
151+ result ["ha_cluster_enable_repos" ] = exporter .export_enable_repos_ha (
152+ dnf_repolist
153+ )
154+ result ["ha_cluster_enable_repos_resilient_storage" ] = (
155+ exporter .export_enable_repos_rs (dnf_repolist )
156+ )
157+
158+ # Cloud agent packages are only handled on RHEL.
159+ installed_packages = loader .get_rpm_installed_packages (cmd_runner )
160+ if installed_packages is not None :
161+ result ["ha_cluster_install_cloud_agents" ] = (
162+ exporter .export_install_cloud_agents (installed_packages )
163+ )
164+
165+ if HAS_FIREWALL :
166+ fw_client = FirewallClient ()
167+ fw_config = loader .get_firewall_config (fw_client )
168+ manage_firewall = False
169+ if fw_config is not None :
170+ manage_firewall = exporter .export_manage_firewall (fw_config )
171+ result ["ha_cluster_manage_firewall" ] = manage_firewall
172+
173+ # ha_cluster_manage_selinux is irrelevant when running the role if
174+ # ha_cluster_manage_firewall is not True
175+ if HAS_SELINUX and manage_firewall :
176+ selinux_ports = SelinuxPortRecords ()
177+ ha_ports_firewall = loader .get_firewall_ha_cluster_ports (fw_client )
178+ ha_ports_selinux = loader .get_selinux_ha_cluster_ports (
179+ selinux_ports
180+ )
181+ if ha_ports_firewall is not None and ha_ports_selinux is not None :
182+ result ["ha_cluster_manage_selinux" ] = (
183+ exporter .export_manage_selinux (
184+ ha_ports_firewall , ha_ports_selinux
185+ )
186+ )
187+
188+ return result
189+
190+
191+ def export_pcsd_configuration () -> Dict [str , Any ]:
192+ """
193+ Export pcsd configuration managed by the role
194+ """
195+ result : dict [str , Any ] = dict ()
196+
197+ pcsd_settings_dict = loader .get_pcsd_settings_conf ()
198+ if pcsd_settings_dict is not None :
199+ pcs_permissions = exporter .export_pcs_permission_list (
200+ pcsd_settings_dict
201+ )
202+ if pcs_permissions is not None :
203+ result ["ha_cluster_pcs_permission_list" ] = pcs_permissions
204+
205+ return result
206+
207+
97208def export_cluster_configuration (module : AnsibleModule ) -> Dict [str , Any ]:
98209 """
99210 Export existing HA cluster configuration
@@ -156,9 +267,13 @@ def main() -> None:
156267
157268 try :
158269 if loader .has_corosync_conf ():
270+ ha_cluster_result .update (** export_os_configuration (module ))
271+ ha_cluster_result .update (** export_pcsd_configuration ())
159272 ha_cluster_result .update (** export_cluster_configuration (module ))
160273 ha_cluster_result ["ha_cluster_cluster_present" ] = True
161274 else :
275+ # Exporting qnetd configuration will be added later here. It will
276+ # probably call export_os and export_pcsd.
162277 ha_cluster_result ["ha_cluster_cluster_present" ] = False
163278 module .exit_json (** module_result )
164279 except exporter .JsonMissingKey as e :
0 commit comments