fix stonith level validation

This commit is contained in:
zouzhimin 2024-02-29 23:46:29 +08:00
parent 0b9032d8ef
commit 7d20b281a4
2 changed files with 274 additions and 1 deletions

View File

@ -0,0 +1,268 @@
From 88ecf0a5728a39f430bb7f709f4c2b6aa59b583e Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Wed, 31 Jan 2024 10:39:12 +0100
Subject: [PATCH] fix stonith level validation
---
CHANGELOG.md | 2 +
pcs/lib/cib/fencing_topology.py | 26 ++++-------
.../tier0/lib/cib/test_fencing_topology.py | 44 +++++++------------
pcs_test/tier1/legacy/test_stonith.py | 24 +++++-----
4 files changed, 39 insertions(+), 57 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 62e7f230..208126ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,10 @@
- Do not put empty uid/gid corosync configuration options to an uidgid file
when not specified in `pcs cluster uidgid add` command. Empty options cause
corosync start failure. ([ghissue#772])
+- Do not allow fencing levels other than 1..9 ([RHEL-2977])
[ghissue#772]: https://github.com/ClusterLabs/pcs/issues/772
+[RHEL-2977]: https://issues.redhat.com/browse/RHEL-2977
## [0.11.7] - 2024-01-11
diff --git a/pcs/lib/cib/fencing_topology.py b/pcs/lib/cib/fencing_topology.py
index 6a9fc71e..2434723b 100644
--- a/pcs/lib/cib/fencing_topology.py
+++ b/pcs/lib/cib/fencing_topology.py
@@ -2,7 +2,6 @@ from typing import (
Optional,
Sequence,
Set,
- Tuple,
)
from lxml import etree
@@ -23,6 +22,7 @@ from pcs.common.reports import codes as report_codes
from pcs.common.reports import has_errors
from pcs.common.reports.item import ReportItem
from pcs.common.types import StringCollection
+from pcs.common.validate import is_integer
from pcs.lib.cib.resource.stonith import is_stonith_resource
from pcs.lib.cib.tools import find_unique_id
from pcs.lib.errors import LibraryError
@@ -60,9 +60,8 @@ def add_level(
bool force_node -- continue even if a node (target) does not exist
"""
# pylint: disable=too-many-arguments
- report_list, valid_level = _validate_level(level)
reporter.report_list(
- report_list
+ _validate_level(level)
+ _validate_target(
cluster_status_nodes, target_type, target_value, force_node
)
@@ -78,7 +77,7 @@ def add_level(
if reporter.has_errors:
raise LibraryError()
_append_level_element(
- topology_el, valid_level, target_type, target_value, devices
+ topology_el, int(level), target_type, target_value, devices
)
@@ -262,22 +261,15 @@ def verify(
return report_list
-def _validate_level(level) -> Tuple[ReportItemList, Optional[int]]:
+def _validate_level(level) -> ReportItemList:
report_list: ReportItemList = []
- try:
- candidate = int(level)
- if candidate > 0:
- return report_list, candidate
- except ValueError:
- pass
- report_list.append(
- ReportItem.error(
- reports.messages.InvalidOptionValue(
- "level", level, "a positive integer"
+ if not is_integer(level, 1, 9):
+ report_list.append(
+ ReportItem.error(
+ reports.messages.InvalidOptionValue("level", level, "1..9")
)
)
- )
- return report_list, None
+ return report_list
def _validate_target(
diff --git a/pcs_test/tier0/lib/cib/test_fencing_topology.py b/pcs_test/tier0/lib/cib/test_fencing_topology.py
index f00d6f31..7c16e15d 100644
--- a/pcs_test/tier0/lib/cib/test_fencing_topology.py
+++ b/pcs_test/tier0/lib/cib/test_fencing_topology.py
@@ -105,7 +105,7 @@ class StatusNodesMixin:
@patch_lib("_validate_level_target_devices_does_not_exist", return_value=[])
@patch_lib("_validate_devices", return_value=[])
@patch_lib("_validate_target", return_value=[])
-@patch_lib("_validate_level", return_value=([], "valid_level"))
+@patch_lib("_validate_level", return_value=[])
class AddLevel(TestCase):
# pylint: disable=too-many-instance-attributes
def setUp(self):
@@ -193,6 +193,7 @@ class AddLevel(TestCase):
mock_val_dupl,
mock_append,
):
+ self.level = 1
lib.add_level(
self.reporter,
self.topology_el,
@@ -210,7 +211,7 @@ class AddLevel(TestCase):
)
mock_append.assert_called_once_with(
self.topology_el,
- "valid_level",
+ self.level,
self.target_type,
self.target_value,
self.devices,
@@ -224,22 +225,17 @@ class AddLevel(TestCase):
mock_val_dupl,
mock_append,
):
- mock_val_level.return_value = (
- [
- reports.item.ReportItem.error(
- reports.messages.InvalidOptionValue(
- "level", self.level, "a positive integer"
- )
- )
- ],
- None,
- )
+ mock_val_level.return_value = [
+ reports.item.ReportItem.error(
+ reports.messages.InvalidOptionValue("level", self.level, "1..9")
+ )
+ ]
report_list = [
fixture.error(
report_codes.INVALID_OPTION_VALUE,
option_value=self.level,
option_name="level",
- allowed_values="a positive integer",
+ allowed_values="1..9",
cannot_be_empty=False,
forbidden_characters=None,
),
@@ -746,25 +742,17 @@ class Verify(TestCase, CibMixin, StatusNodesMixin):
class ValidateLevel(TestCase):
def test_success(self):
- level_list = [
- (1, 1),
- ("1", 1),
- (9, 9),
- ("9", 9),
- ("05", 5),
- ]
- for level_in, level_out in level_list:
- with self.subTest(level=level_in):
- report_list, valid_level = lib._validate_level(level_in)
- self.assertEqual(level_out, valid_level)
+ level_list = [1, "1", 9, "9", "05"]
+ for level in level_list:
+ with self.subTest(level=level):
+ report_list = lib._validate_level(level)
assert_report_item_list_equal(report_list, [])
def test_invalid(self):
- level_list = ["", 0, "0", -1, "-1", "1abc"]
+ level_list = ["", 0, "0", -1, "-1", "1abc", "10"]
for level in level_list:
with self.subTest(level=level):
- report_list, valid_level = lib._validate_level(level)
- self.assertEqual(None, valid_level)
+ report_list = lib._validate_level(level)
assert_report_item_list_equal(
report_list,
[
@@ -772,7 +760,7 @@ class ValidateLevel(TestCase):
report_codes.INVALID_OPTION_VALUE,
option_value=level,
option_name="level",
- allowed_values="a positive integer",
+ allowed_values="1..9",
cannot_be_empty=False,
forbidden_characters=None,
),
diff --git a/pcs_test/tier1/legacy/test_stonith.py b/pcs_test/tier1/legacy/test_stonith.py
index 76dd11c3..b293f1a7 100644
--- a/pcs_test/tier1/legacy/test_stonith.py
+++ b/pcs_test/tier1/legacy/test_stonith.py
@@ -2227,36 +2227,36 @@ class LevelAdd(LevelTestsBase):
self.assert_pcs_fail(
"stonith level add NaN rh7-1 F1".split(),
(
- "Error: 'NaN' is not a valid level value, use a positive "
- "integer\n" + ERRORS_HAVE_OCCURRED
+ "Error: 'NaN' is not a valid level value, use 1..9\n"
+ + ERRORS_HAVE_OCCURRED
),
)
self.assert_pcs_fail(
"-- stonith level add -10 rh7-1 F1".split(),
(
- "Error: '-10' is not a valid level value, use a positive "
- "integer\n" + ERRORS_HAVE_OCCURRED
+ "Error: '-10' is not a valid level value, use 1..9\n"
+ + ERRORS_HAVE_OCCURRED
),
)
self.assert_pcs_fail(
"stonith level add 10abc rh7-1 F1".split(),
(
- "Error: '10abc' is not a valid level value, use a positive "
- "integer\n" + ERRORS_HAVE_OCCURRED
+ "Error: '10abc' is not a valid level value, use 1..9\n"
+ + ERRORS_HAVE_OCCURRED
),
)
self.assert_pcs_fail(
"stonith level add 0 rh7-1 F1".split(),
(
- "Error: '0' is not a valid level value, use a positive "
- "integer\n" + ERRORS_HAVE_OCCURRED
+ "Error: '0' is not a valid level value, use 1..9\n"
+ + ERRORS_HAVE_OCCURRED
),
)
self.assert_pcs_fail(
"stonith level add 000 rh7-1 F1".split(),
(
- "Error: '000' is not a valid level value, use a positive "
- "integer\n" + ERRORS_HAVE_OCCURRED
+ "Error: '000' is not a valid level value, use 1..9\n"
+ + ERRORS_HAVE_OCCURRED
),
)
@@ -2273,7 +2273,7 @@ class LevelAdd(LevelTestsBase):
self.assert_pcs_fail(
"stonith level add x rh7-X F0 dev@ce".split(),
(
- "Error: 'x' is not a valid level value, use a positive integer\n"
+ "Error: 'x' is not a valid level value, use 1..9\n"
"Error: Node 'rh7-X' does not appear to exist in configuration, "
"use --force to override\n"
"Error: invalid device id 'dev@ce', '@' is not a valid character "
@@ -2286,7 +2286,7 @@ class LevelAdd(LevelTestsBase):
self.assert_pcs_fail(
"stonith level add x rh7-X F0 dev@ce --force".split(),
(
- "Error: 'x' is not a valid level value, use a positive integer\n"
+ "Error: 'x' is not a valid level value, use 1..9\n"
"Warning: Node 'rh7-X' does not appear to exist in configuration\n"
"Error: invalid device id 'dev@ce', '@' is not a valid character "
"for a device id\n"
--
2.25.1

View File

@ -1,6 +1,6 @@
Name: pcs Name: pcs
Version: 0.11.7 Version: 0.11.7
Release: 2 Release: 3
License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later) License: GPL-2.0-only AND Apache-2.0 AND MIT AND BSD-3-Clause AND (BSD-2-Clause OR Ruby) AND (BSD-2-Clause OR GPL-2.0-or-later)
URL: https://github.com/ClusterLabs/pcs URL: https://github.com/ClusterLabs/pcs
Group: System Environment/Base Group: System Environment/Base
@ -39,6 +39,8 @@ Source4: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_commit
Patch0: do-not-support-cluster-setup-with-udp-u-transport.patch Patch0: do-not-support-cluster-setup-with-udp-u-transport.patch
Patch1: Support-for-openEuler.patch Patch1: Support-for-openEuler.patch
Patch2: fix-do-not-put-empty-uid-gid-options-to-an-uidgid-fi.patch Patch2: fix-do-not-put-empty-uid-gid-options-to-an-uidgid-fi.patch
Patch3: fix-stonith-level-validation.patch
# ui patches: >200 # ui patches: >200
# Patch201: bzNUMBER-01-name.patch # Patch201: bzNUMBER-01-name.patch
@ -398,6 +400,9 @@ run_all_tests
%license pyagentx_LICENSE.txt %license pyagentx_LICENSE.txt
%changelog %changelog
* Mon Mar 04 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-3
- fix stonith level validation
* Fri Mar 01 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-2 * Fri Mar 01 2024 zouzhimin <zouzhimin@kylinos.cn> - 0.11.7-2
- fixed command `pcs cluster uidgid add` - fixed command `pcs cluster uidgid add`