Skip to content

Commit 236ee2f

Browse files
committed
Hotfix to enhance code clarity, and update configurations for high availability (HA) systems (#69)
1 parent 604dd15 commit 236ee2f

20 files changed

+207
-131
lines changed

docs/HIGH_AVAILABILITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ For the framework to access the properties of the Azure Load Balancer in a high
6565
1. Enable system managed identity on the management server by following the steps in [Configure managed identities on Azure VMs](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-configure-managed-identities?pivots=qs-configure-portal-windows-vm#system-assigned-managed-identity).
6666
1. Open the Azure Load Balancer used for the high availability deployment of your SAP system on Azure.
6767
1. In the Azure Load Balancer panel, go to Access control (IAM).
68-
1. Follow steps 5 to 10 from [Use managed identity to access Azure Resource](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-configure-managed-identities?pivots=qs-configure-portal-windows-vm#system-assigned-managed-identity) to complete the configuration.
68+
1. Follow steps from [Use managed identity to access Azure Resource](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal) to complete the configuration.
6969

7070
#### Configuring access using user-assigned managed identity
7171

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ cryptography==44.0.2
8080
# azure-storage-queue
8181
# msal
8282
# pyjwt
83-
dill==0.3.9
83+
dill==0.4.0
8484
# via pylint
8585
exceptiongroup==1.2.2
8686
# via pytest
@@ -130,11 +130,11 @@ msal-extensions==1.3.1
130130
# via azure-identity
131131
mypy-extensions==1.0.0
132132
# via black
133-
numpy==2.2.4
133+
numpy==2.2.5
134134
# via
135135
# -r requirements.in
136136
# pandas
137-
packaging==24.2
137+
packaging==25.0
138138
# via
139139
# ansible-compat
140140
# ansible-core

src/module_utils/commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@
3333
]
3434

3535

36-
FREEZE_FILESYSTEM = lambda file_system: [
36+
FREEZE_FILESYSTEM = lambda file_system, mount_point: [
3737
"mount",
3838
"-o",
3939
"ro",
4040
file_system,
41-
"/hana/shared",
41+
mount_point,
4242
]
4343

4444
PACEMAKER_STATUS = ["systemctl", "is-active", "pacemaker"]

src/modules/check_indexserver.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,20 @@ def check_indexserver(self) -> None:
116116
}
117117
},
118118
],
119-
"suse": {
120-
"[ha_dr_provider_suschksrv]": {
121-
"provider": "susChkSrv",
122-
"path": "/usr/share/SAPHanaSR",
123-
}
124-
},
119+
"suse": [
120+
{
121+
"[ha_dr_provider_suschksrv]": {
122+
"provider": "susChkSrv",
123+
"path": "/usr/share/SAPHanaSR",
124+
},
125+
},
126+
{
127+
"[ha_dr_provider_suschksrv]": {
128+
"provider": "susChkSrv",
129+
"path": "/hana/shared/myHooks",
130+
}
131+
},
132+
],
125133
}
126134

127135
os_props_list = expected_properties.get(self.os_distribution)

src/modules/filesystem_freeze.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"""
77

88
import logging
9-
from typing import Dict, Any
9+
from typing import Dict, Any, Tuple
1010
from ansible.module_utils.basic import AnsibleModule
1111

1212
try:
@@ -94,12 +94,14 @@ def __init__(self, database_sid: str) -> None:
9494
super().__init__()
9595
self.database_sid = database_sid
9696

97-
def _find_filesystem(self) -> str:
97+
def _find_filesystem(self) -> Tuple[str, str]:
9898
"""
9999
Find the filesystem mounted on /hana/shared.
100+
This method reads the /proc/mounts file to identify the filesystem.
101+
It returns the filesystem device and the mount point as /hana/shared.
100102
101103
:return: The filesystem mounted on /hana/shared.
102-
:rtype: str
104+
:rtype: Tuple[str, str]
103105
"""
104106
try:
105107
with open("/proc/mounts", "r", encoding="utf-8") as mounts_file:
@@ -109,10 +111,10 @@ def _find_filesystem(self) -> str:
109111
"/hana/shared",
110112
f"/hana/shared/{self.database_sid}",
111113
]:
112-
return parts[0]
114+
return parts[0], "/hana/shared"
113115
except FileNotFoundError as ex:
114116
self.handle_error(ex)
115-
return None
117+
return None, None
116118

117119
def run(self) -> Dict[str, Any]:
118120
"""
@@ -121,22 +123,24 @@ def run(self) -> Dict[str, Any]:
121123
:return: A dictionary containing the result of the test case.
122124
:rtype: Dict[str, Any]
123125
"""
124-
file_system = self._find_filesystem()
126+
file_system, mount_point = self._find_filesystem()
125127

126-
self.log(
127-
logging.INFO,
128-
f"Found the filesystem mounted on /hana/shared: {file_system}",
129-
)
130-
131-
if file_system:
132-
read_only_output = self.execute_command_subprocess(FREEZE_FILESYSTEM(file_system))
128+
if file_system and mount_point:
129+
self.log(
130+
logging.INFO,
131+
f"Found the filesystem mounted on: {file_system} at {mount_point}",
132+
)
133+
read_only_output = self.execute_command_subprocess(
134+
FREEZE_FILESYSTEM(file_system, mount_point)
135+
)
133136
self.log(logging.INFO, read_only_output)
134137
self.result.update(
135138
{
136139
"changed": True,
137-
"message": "The file system (/hana/shared) was successfully mounted read-only.",
140+
"message": f"The file system ({mount_point}) was mounted read-only.",
138141
"status": TestStatus.SUCCESS.value,
139142
"details": read_only_output,
143+
"mount_point": mount_point,
140144
}
141145
)
142146
else:

src/modules/get_pcmk_properties_db.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ class HAClusterValidator(SapAutomationQA):
177177
CONSTRAINTS_CATEGORIES = (".//*", "CONSTRAINTS_DEFAULTS")
178178

179179
RESOURCE_CATEGORIES = {
180-
"stonith": ".//primitive[@class='stonith']",
180+
"sbd_stonith": ".//primitive[@type='external/sbd']",
181+
"fence_agent": ".//primitive[@type='fence_azure_arm']",
181182
"topology": ".//clone/primitive[@type='SAPHanaTopology']",
182183
"topology_meta": ".//clone/meta_attributes",
183184
"hana": ".//master/primitive[@type='SAPHana']",
@@ -242,12 +243,9 @@ def _get_resource_expected_value(self, resource_type, section, param_name, op_na
242243
:return: The expected value for the resource configuration parameter.
243244
:rtype: str
244245
"""
245-
resource_defaults = self.constants["RESOURCE_DEFAULTS"].get(self.os_type, {})
246-
247-
if resource_type == "stonith":
248-
resource_defaults = resource_defaults.get("stonith", {}).get(self.fencing_mechanism, {})
249-
else:
250-
resource_defaults = resource_defaults.get(resource_type, {})
246+
resource_defaults = (
247+
self.constants["RESOURCE_DEFAULTS"].get(self.os_type, {}).get(resource_type, {})
248+
)
251249

252250
if section == "meta_attributes":
253251
return resource_defaults.get("meta_attributes", {}).get(param_name)
@@ -333,16 +331,20 @@ def _parse_nvpair_elements(self, elements, category, subcategory=None, op_name=N
333331
"""
334332
parameters = []
335333
for nvpair in elements:
336-
parameters.append(
337-
self._create_parameter(
338-
category=category,
339-
subcategory=subcategory,
340-
op_name=op_name,
341-
id=nvpair.get("id", ""),
342-
name=nvpair.get("name", ""),
343-
value=nvpair.get("value", ""),
334+
name = nvpair.get("name", "")
335+
if name in ["passwd", "password", "login"]:
336+
continue
337+
else:
338+
parameters.append(
339+
self._create_parameter(
340+
category=category,
341+
subcategory=subcategory,
342+
op_name=op_name,
343+
id=nvpair.get("id", ""),
344+
name=name,
345+
value=nvpair.get("value", ""),
346+
)
344347
)
345-
)
346348
return parameters
347349

348350
def _parse_os_parameters(self):
@@ -404,6 +406,9 @@ def _parse_global_ini_parameters(self):
404406

405407
for param_name, expected_value in global_ini_defaults.items():
406408
value = global_ini_properties.get(param_name, "")
409+
if isinstance(expected_value, list):
410+
if value in expected_value:
411+
expected_value = value
407412
parameters.append(
408413
self._create_parameter(
409414
category="global_ini",

src/modules/get_pcmk_properties_scs.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -327,16 +327,20 @@ def _parse_nvpair_elements(self, elements, category, subcategory=None, op_name=N
327327
"""
328328
parameters = []
329329
for nvpair in elements:
330-
parameters.append(
331-
self._create_parameter(
332-
category=category,
333-
subcategory=subcategory,
334-
op_name=op_name,
335-
id=nvpair.get("id", ""),
336-
name=nvpair.get("name", ""),
337-
value=nvpair.get("value", ""),
330+
name = nvpair.get("name", "")
331+
if name in ["passwd", "password", "login"]:
332+
continue
333+
else:
334+
parameters.append(
335+
self._create_parameter(
336+
category=category,
337+
subcategory=subcategory,
338+
op_name=op_name,
339+
id=nvpair.get("id", ""),
340+
name=name,
341+
value=nvpair.get("value", ""),
342+
)
338343
)
339-
)
340344
return parameters
341345

342346
def _parse_resource(self, element, category):

src/roles/ha_db_hana/tasks/azure-lb.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@
1313
- name: "Pre Validations: Validate the Azure Load Balancer config"
1414
become: true
1515
block:
16-
- name: "Install azure management network package"
17-
ansible.builtin.pip:
18-
name: "azure-mgmt-network"
19-
state: present
20-
2116
- name: "Retrieve Subscription ID and Resource Group Name"
2217
ansible.builtin.uri:
2318
url: http://169.254.169.254/metadata/instance?api-version=2021-02-01

src/roles/ha_db_hana/tasks/block-network.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
delegate_to: localhost
5757
ansible.builtin.shell: |
5858
for i in $(seq 1 30); do
59-
if ! ping -c 1 -w 1 {{ ansible_host }}; then
59+
if ! nc -zv -w1 {{ ansible_host }} {{ sap_port_to_ping }}; then
6060
echo "Connection failed on attempt $i"
6161
exit 1
6262
fi

src/roles/ha_db_hana/tasks/files/constants.yaml

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ VALID_CONFIGS:
4747
SUSE: {}
4848
AFA:
4949
have-watchdog: "false"
50-
stonith-timeout: "900"
50+
stonith-timeout: "900s"
5151
ISCSI:
5252
have-watchdog: "true"
5353
stonith-timeout: "144s"
@@ -57,30 +57,31 @@ VALID_CONFIGS:
5757
# cibadmin --query --scope resources
5858
RESOURCE_DEFAULTS:
5959
SUSE:
60-
stonith:
61-
AFA:
62-
instance_attributes:
63-
pcmk_delay_max: "30s"
64-
pcmk_monitor_retries: "4"
65-
pcmk_action_limit: "3"
66-
pcmk_reboot_timeout: "900"
67-
power_timeout: "240"
68-
pcmk_monitor_timeout: "120"
69-
operations:
70-
monitor:
71-
interval: "3600"
72-
ISCSI:
73-
instance_attributes:
74-
pcmk_delay_max: "30s"
75-
pcmk_monitor_retries: "4"
76-
pcmk_action_limit: "3"
77-
pcmk_reboot_timeout: "900"
78-
power_timeout: "240"
79-
pcmk_monitor_timeout: "120"
80-
operations:
81-
monitor:
82-
interval: "600"
83-
timeout: "15"
60+
fence_agent:
61+
instance_attributes:
62+
pcmk_delay_max: "15"
63+
pcmk_monitor_retries: "4"
64+
pcmk_action_limit: "3"
65+
pcmk_reboot_timeout: "900"
66+
power_timeout: "240"
67+
pcmk_monitor_timeout: "120"
68+
operations:
69+
monitor:
70+
interval: "3600"
71+
timeout: "120"
72+
73+
sbd_stonith:
74+
instance_attributes:
75+
pcmk_delay_max: "15"
76+
pcmk_monitor_retries: "4"
77+
pcmk_action_limit: "3"
78+
pcmk_reboot_timeout: "900"
79+
power_timeout: "240"
80+
pcmk_monitor_timeout: "120"
81+
operations:
82+
monitor:
83+
interval: "600"
84+
timeout: "15"
8485

8586
topology:
8687
meta_attributes:
@@ -151,29 +152,29 @@ RESOURCE_DEFAULTS:
151152
resource-stickiness: "0"
152153

153154
REDHAT:
154-
stonith:
155-
AFA:
156-
instance_attributes:
157-
pcmk_delay_max: "30s"
158-
pcmk_monitor_retries: "4"
159-
pcmk_action_limit: "3"
160-
pcmk_reboot_timeout: "900"
161-
power_timeout: "240"
162-
pcmk_monitor_timeout: "120"
163-
operations:
164-
monitor:
165-
interval: "3600"
166-
ISCSI:
167-
instance_attributes:
168-
pcmk_monitor_retries: "4"
169-
pcmk_action_limit: "3"
170-
pcmk_reboot_timeout: "900"
171-
power_timeout: "240"
172-
pcmk_monitor_timeout: "120"
173-
operations:
174-
monitor:
175-
interval: "600"
176-
timeout: "15"
155+
fence_agent:
156+
instance_attributes:
157+
pcmk_delay_max: "15"
158+
pcmk_monitor_retries: "4"
159+
pcmk_action_limit: "3"
160+
pcmk_reboot_timeout: "900"
161+
power_timeout: "240"
162+
pcmk_monitor_timeout: "120"
163+
operations:
164+
monitor:
165+
interval: "3600"
166+
167+
sbd_stonith:
168+
instance_attributes:
169+
pcmk_monitor_retries: "4"
170+
pcmk_action_limit: "3"
171+
pcmk_reboot_timeout: "900"
172+
power_timeout: "240"
173+
pcmk_monitor_timeout: "120"
174+
operations:
175+
monitor:
176+
interval: "600"
177+
timeout: "15"
177178

178179
topology:
179180
meta_attributes:
@@ -285,7 +286,7 @@ OS_PARAMETERS:
285286
GLOBAL_INI:
286287
SUSE:
287288
provider: "SAPHanaSR"
288-
path: "/usr/share/SAPHanaSR"
289+
path: ["/usr/share/SAPHanaSR", "/hana/shared/myHooks"]
289290
execution_order: "1"
290291

291292
REDHAT:

0 commit comments

Comments
 (0)