Skip to content

Commit 368ed5d

Browse files
committed
Refactor node attribute processing in cluster status checkers and update validation tasks in kill-enqueue-server.yml
1 parent d285fdd commit 368ed5d

4 files changed

Lines changed: 72 additions & 29 deletions

File tree

src/module_utils/get_cluster_status.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def _validate_cluster_basic_status(self, cluster_status_xml: ET.Element):
8686
self.result["message"] = f"Node {node.attrib['name']} is not online"
8787
self.log(logging.WARNING, self.result["message"])
8888

89-
def _process_node_attributes(self, node_attributes: ET.Element) -> Dict[str, Any]:
89+
def _process_node_attributes(self, cluster_status_xml: ET.Element) -> Dict[str, Any]:
9090
"""
9191
Abstract method to process node attributes.
9292
@@ -115,7 +115,7 @@ def run(self) -> Dict[str, str]:
115115
self.log(logging.INFO, "Cluster status retrieved")
116116

117117
self._validate_cluster_basic_status(cluster_status_xml)
118-
self._process_node_attributes(cluster_status_xml.find("node_attributes"))
118+
self._process_node_attributes(cluster_status_xml=cluster_status_xml)
119119

120120
if not self._is_cluster_stable():
121121
self.result["message"] = "Pacemaker cluster isn't stable"

src/modules/get_cluster_status_db.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,12 @@ def _get_automation_register(self) -> None:
155155
except Exception:
156156
self.result["AUTOMATED_REGISTER"] = "unknown"
157157

158-
def _process_node_attributes(self, node_attributes: ET.Element) -> Dict[str, Any]:
158+
def _process_node_attributes(self, cluster_status_xml: ET.Element) -> Dict[str, Any]:
159159
"""
160160
Processes node attributes and identifies primary and secondary nodes.
161161
162-
:param node_attributes: XML element containing node attributes.
163-
:type node_attributes: ET.Element
162+
:param cluster_status_xml: XML element containing node attributes.
163+
:type cluster_status_xml: ET.Element
164164
:return: Dictionary with primary and secondary node information.
165165
:rtype: Dict[str, Any]
166166
"""
@@ -172,7 +172,7 @@ def _process_node_attributes(self, node_attributes: ET.Element) -> Dict[str, Any
172172
"replication_mode": "",
173173
"primary_site_name": "",
174174
}
175-
175+
node_attributes = cluster_status_xml.find("node_attributes")
176176
attribute_map = {
177177
f"hana_{self.database_sid}_op_mode": "operation_mode",
178178
f"hana_{self.database_sid}_srmode": "replication_mode",

src/modules/get_cluster_status_scs.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,38 @@ class SCSClusterStatusChecker(BaseClusterStatusChecker):
9191
Class to check the status of a pacemaker cluster in an SAP SCS environment.
9292
"""
9393

94-
def __init__(self, sap_sid: str, ansible_os_family: str = ""):
94+
def __init__(
95+
self,
96+
sap_sid: str,
97+
ansible_os_family: str = "",
98+
ascs_instance_number: str = "00",
99+
ers_instance_number: str = "01",
100+
):
95101
super().__init__(ansible_os_family)
96102
self.sap_sid = sap_sid
103+
self.ascs_instance_number = ascs_instance_number
104+
self.ers_instance_number = ers_instance_number
97105
self.result.update(
98106
{
99107
"ascs_node": "",
100108
"ers_node": "",
101109
}
102110
)
103111

104-
def _process_node_attributes(self, node_attributes: ET.Element) -> Dict[str, Any]:
112+
def _process_node_attributes(self, cluster_status_xml: ET.Element) -> Dict[str, Any]:
105113
"""
106114
Processes node attributes and identifies ASCS and ERS nodes.
107115
108-
:param node_attributes: XML element containing node attributes.
109-
:type node_attributes: ET.Element
116+
:param cluster_status_xml: XML element containing node attributes.
117+
:type cluster_status_xml: ET.Element
110118
:return: Dictionary with ASCS and ERS node information.
111119
:rtype: Dict[str, Any]
112120
"""
121+
resources = cluster_status_xml.find("resources")
122+
node_attributes = cluster_status_xml.find("node_attributes")
123+
ascs_resource_id = f"rsc_sap_{self.sap_sid.upper()}_ASCS{self.ascs_instance_number}"
124+
ers_resource_id = f"rsc_sap_{self.sap_sid.upper()}_ERS{self.ers_instance_number}"
125+
113126
all_nodes = [node.attrib.get("name") for node in node_attributes]
114127
for node in node_attributes:
115128
node_name = node.attrib["name"]
@@ -120,20 +133,42 @@ def _process_node_attributes(self, node_attributes: ET.Element) -> Dict[str, Any
120133
else:
121134
self.result["ascs_node"] = node_name
122135

123-
if self.result["ascs_node"] == "" and self.result["ers_node"] != "":
124-
self.result["ascs_node"] = next(
125-
(n for n in all_nodes if n != self.result["ers_node"]), ""
126-
)
136+
if resources is not None:
137+
ascs_resource = resources.find(f"./resource[@id='{ascs_resource_id}']")
138+
ers_resource = resources.find(f"./resource[@id='{ers_resource_id}']")
139+
140+
if ascs_resource is not None:
141+
is_failed = ascs_resource.attrib.get("is_failed", "false").lower() == "true"
142+
if not is_failed:
143+
node_element = ascs_resource.find("node")
144+
if node_element is not None:
145+
self.result["ascs_node"] = node_element.attrib.get(
146+
"name", self.result["ascs_node"]
147+
)
148+
else:
149+
self.result["ascs_node"] = ""
150+
151+
if ers_resource is not None:
152+
is_failed = ers_resource.attrib.get("is_failed", "false").lower() == "true"
153+
if not is_failed:
154+
node_element = ers_resource.find("node")
155+
if node_element is not None:
156+
self.result["ers_node"] = node_element.attrib.get(
157+
"name", self.result["ers_node"]
158+
)
159+
else:
160+
self.result["ers_node"] = ""
161+
127162
return self.result
128163

129164
def _is_cluster_ready(self) -> bool:
130165
"""
131-
Check if the cluster is ready by verifying the ASCS node.
166+
Check if the cluster is ready by verifying at least one of ASCS or ERS nodes.
132167
133-
:return: True if the cluster is ready, False otherwise.
168+
:return: True if either ASCS or ERS node is available, False otherwise.
134169
:rtype: bool
135170
"""
136-
return self.result["ascs_node"] != ""
171+
return self.result["ascs_node"] != "" or self.result["ers_node"] != ""
137172

138173
def _is_cluster_stable(self) -> bool:
139174
"""
@@ -151,6 +186,8 @@ def run_module() -> None:
151186
"""
152187
module_args = dict(
153188
sap_sid=dict(type="str", required=True),
189+
ascs_instance_number=dict(type="str", required=False),
190+
ers_instance_number=dict(type="str", required=False),
154191
ansible_os_family=dict(type="str", required=False),
155192
)
156193

src/roles/ha_scs/tasks/kill-enqueue-server.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,8 @@
5050
failed_when: false
5151
when: ensa2_check.stdout != "0"
5252

53-
- name: "Test Execution: Wait for Failover"
54-
ansible.builtin.pause:
55-
seconds: 60
56-
57-
- name: "Test Execution: Validate SCS cluster status"
53+
- name: "Test Execution: Validate SCS cluster status for ENSA1"
54+
when: ensa2_check.stdout == "0"
5855
get_cluster_status_scs:
5956
sap_sid: "{{ sap_sid | lower }}"
6057
ansible_os_family: "{{ ansible_os_family | upper }}"
@@ -66,10 +63,19 @@
6663
cluster_status_test_execution.ascs_node == cluster_status_pre.ers_node
6764
and cluster_status_test_execution.ers_node == cluster_status_pre.ascs_node
6865
69-
- name: "Test Execution: Cleanup on ASCS Node"
70-
when: ansible_hostname == cluster_status_pre.ascs_node
71-
become: true
72-
block:
66+
- name: "Test Execution: Validate SCS cluster status for ENSA2"
67+
when: ensa2_check.stdout != "0"
68+
get_cluster_status_scs:
69+
sap_sid: "{{ sap_sid | lower }}"
70+
ansible_os_family: "{{ ansible_os_family | upper }}"
71+
register: cluster_status_test_execution
72+
retries: 50
73+
delay: 10
74+
failed_when: false
75+
until: |
76+
cluster_status_test_execution.ascs_node != ""
77+
and cluster_status_test_execution.ers_node != ""
78+
7379
- name: "Test Execution: Cleanup resources"
7480
ansible.builtin.command: crm_resource --cleanup
7581
register: cleanup_failed_resource_test_execution
@@ -83,15 +89,15 @@
8389
ansible.builtin.set_fact:
8490
test_case_message_from_test_case: |
8591
Old ASCS: {{ cluster_status_pre.ascs_node }}
86-
New ASCS: {{ hostvars[cluster_status_pre.ascs_node].cluster_status_test_execution.ascs_node }}
92+
New ASCS: {{ cluster_status_test_execution.ascs_node }}
8793
Old ERS: {{ cluster_status_pre.ers_node }}
88-
New ERS: {{ hostvars[cluster_status_pre.ascs_node].cluster_status_test_execution.ers_node }}
94+
New ERS: {{ cluster_status_test_execution.ers_node }}
8995
test_case_details_from_test_case: {
9096
"Pre Validations: Validate SCS cluster status": "{{ cluster_status_pre }}",
9197
"Pre Validations: CleanUp any failed resource": "{{ cleanup_failed_resource_pre }}",
9298
"Test Execution: Kill Enqueue Server Process": "{{ kill_en_result }}",
9399
"Test Execution: Cleanup resources": "{{ cleanup_failed_resource_test_execution }}",
94-
"Post Validations Result": "{{ hostvars[cluster_status_pre.ers_node].cluster_status_test_execution }}",
100+
"Post Validations Result": "{{ cluster_status_test_execution }}",
95101
}
96102
# /*---------------------------------------------------------------------------
97103
# | Post Validations |

0 commit comments

Comments
 (0)