From b52c3ed9ec342b021357b915eaf6581f9f6a57d2 Mon Sep 17 00:00:00 2001
From: Ondrej Mular <omular@redhat.com>
Date: Fri, 31 Aug 2018 10:12:18 +0200
Subject: [PATCH] fix allowed instance attrs for some fence agents
Fix is effective only for agents `fence_compute` and `fence_evacuate`
---
pcs/lib/resource_agent.py | 22 ++++++++++++-
pcs/lib/test/test_resource_agent.py | 50 +++++++++++++++++++++++++++++
pcs/test/test_stonith.py | 63 +++++++++++++++++++++++++++++++++++++
3 files changed, 134 insertions(+), 1 deletion(-)
diff --git a/pcs/lib/resource_agent.py b/pcs/lib/resource_agent.py
index 34b18b9b..447cf1fe 100644
--- a/pcs/lib/resource_agent.py
+++ b/pcs/lib/resource_agent.py
@@ -469,6 +469,14 @@ class Agent(object):
"obsoletes": parameter_element.get("obsoletes", None),
})
+ def _get_always_allowed_parameters(self):
+ """
+ This method should be overriden in descendants.
+
+ Returns set of always allowed parameters of a agent.
+ """
+ return set()
+
def validate_parameters(
self, parameters,
parameters_type="resource",
@@ -518,13 +526,17 @@ class Agent(object):
agent_params = self.get_parameters()
required_missing = []
+ always_allowed = self._get_always_allowed_parameters()
for attr in agent_params:
if attr["required"] and attr["name"] not in parameters_values:
required_missing.append(attr["name"])
valid_attrs = [attr["name"] for attr in agent_params]
return (
- [attr for attr in parameters_values if attr not in valid_attrs],
+ [
+ attr for attr in parameters_values
+ if attr not in valid_attrs and attr not in always_allowed
+ ],
required_missing
)
@@ -858,6 +870,14 @@ class StonithAgent(CrmAgent):
self._get_stonithd_metadata().get_parameters()
)
+ def _get_always_allowed_parameters(self):
+ if self.get_name() in ("fence_compute", "fence_evacuate"):
+ return set([
+ "project-domain", "project_domain", "user-domain",
+ "user_domain", "compute-domain", "compute_domain",
+ ])
+ return set()
+
def validate_parameters(
self, parameters,
parameters_type="stonith",
diff --git a/pcs/lib/test/test_resource_agent.py b/pcs/lib/test/test_resource_agent.py
index 4ec94e26..2396bf30 100644
--- a/pcs/lib/test/test_resource_agent.py
+++ b/pcs/lib/test/test_resource_agent.py
@@ -1275,6 +1275,23 @@ class AgentMetadataValidateParametersValuesTest(TestCase):
(["obsoletes"], ["deprecated"])
)
+ @patch_agent_object(
+ "_get_always_allowed_parameters",
+ lambda self: set(["always_allowed", "another-one", "last_one"])
+ )
+ def test_always_allowed(self, mock_metadata):
+ mock_metadata.return_value = self.metadata
+ self.assertEqual(
+ self.agent.validate_parameters_values({
+ "another_required_param": "value1",
+ "required_param": "value2",
+ "test_param": "value3",
+ "always_allowed": "value4",
+ "another-one": "value5",
+ }),
+ ([], [])
+ )
+
class AgentMetadataValidateParameters(TestCase):
def setUp(self):
@@ -2175,3 +2192,36 @@ class AbsentResourceAgentTest(TestCase):
self.assertEqual(([], []), absent.validate_parameters_values({
"whatever": "anything"
}))
+
+
+class StonithAgentAlwaysAllowedParametersTest(TestCase):
+ def setUp(self):
+ self.runner = mock.MagicMock(spec_set=CommandRunner)
+ self.always_allowed = set([
+ "project-domain", "project_domain", "user-domain", "user_domain",
+ "compute-domain", "compute_domain",
+ ])
+
+ def test_fence_compute(self):
+ self.assertEquals(
+ self.always_allowed,
+ lib_ra.StonithAgent(
+ self.runner, "fence_compute"
+ )._get_always_allowed_parameters()
+ )
+
+ def test_fence_evacuate(self):
+ self.assertEquals(
+ self.always_allowed,
+ lib_ra.StonithAgent(
+ self.runner, "fence_evacuate"
+ )._get_always_allowed_parameters()
+ )
+
+ def test_some_other_agent(self):
+ self.assertEquals(
+ set(),
+ lib_ra.StonithAgent(
+ self.runner, "fence_dummy"
+ )._get_always_allowed_parameters()
+ )
diff --git a/pcs/test/test_stonith.py b/pcs/test/test_stonith.py
index cdb2ecee..ff981acc 100644
--- a/pcs/test/test_stonith.py
+++ b/pcs/test/test_stonith.py
@@ -469,6 +469,69 @@ class StonithTest(TestCase, AssertPcsMixin):
)
)
+ def test_stonith_compute_evacuate_always_allowed_parameters(self):
+ self.assert_pcs_success(
+ "stonith create test1 fence_compute auth_url=test1 project_domain=val1 project-domain=val2 user_domain=val3 user-domain=val4 compute_domain=val5 compute-domain=val6",
+ )
+ self.assert_pcs_success(
+ "stonith show --full",
+ outdent(
+ """\
+ Resource: test1 (class=stonith type=fence_compute)
+ Attributes: auth_url=test1 compute-domain=val6 compute_domain=val5 project-domain=val2 project_domain=val1 user-domain=val4 user_domain=val3
+ Operations: monitor interval=60s (test1-monitor-interval-60s)
+ """
+ )
+ )
+ self.assert_pcs_success(
+ "stonith create test2 fence_evacuate auth_url=test2 project_domain=val0 project-domain=val1 user_domain=val2 user-domain=val3 compute_domain=val4 compute-domain=val5",
+ )
+ self.assert_pcs_success(
+ "stonith show --full",
+ outdent(
+ """\
+ Resource: test1 (class=stonith type=fence_compute)
+ Attributes: auth_url=test1 compute-domain=val6 compute_domain=val5 project-domain=val2 project_domain=val1 user-domain=val4 user_domain=val3
+ Operations: monitor interval=60s (test1-monitor-interval-60s)
+ Resource: test2 (class=stonith type=fence_evacuate)
+ Attributes: auth_url=test2 compute-domain=val5 compute_domain=val4 project-domain=val1 project_domain=val0 user-domain=val3 user_domain=val2
+ Operations: monitor interval=60s (test2-monitor-interval-60s)
+ """
+ )
+ )
+ self.assert_pcs_success(
+ "stonith update test1 auth_url=new0 project_domain=new1 project-domain=new2 user_domain=new3 user-domain=new4 compute_domain=new5 compute-domain=new6",
+ )
+ self.assert_pcs_success(
+ "stonith show --full",
+ outdent(
+ """\
+ Resource: test1 (class=stonith type=fence_compute)
+ Attributes: auth_url=new0 compute-domain=new6 compute_domain=new5 project-domain=new2 project_domain=new1 user-domain=new4 user_domain=new3
+ Operations: monitor interval=60s (test1-monitor-interval-60s)
+ Resource: test2 (class=stonith type=fence_evacuate)
+ Attributes: auth_url=test2 compute-domain=val5 compute_domain=val4 project-domain=val1 project_domain=val0 user-domain=val3 user_domain=val2
+ Operations: monitor interval=60s (test2-monitor-interval-60s)
+ """
+ )
+ )
+ self.assert_pcs_success(
+ "stonith update test2 auth_url=new1 project_domain=new2 project-domain=new3 user_domain=new4 user-domain=new5 compute_domain=new6 compute-domain=new7",
+ )
+ self.assert_pcs_success(
+ "stonith show --full",
+ outdent(
+ """\
+ Resource: test1 (class=stonith type=fence_compute)
+ Attributes: auth_url=new0 compute-domain=new6 compute_domain=new5 project-domain=new2 project_domain=new1 user-domain=new4 user_domain=new3
+ Operations: monitor interval=60s (test1-monitor-interval-60s)
+ Resource: test2 (class=stonith type=fence_evacuate)
+ Attributes: auth_url=new1 compute-domain=new7 compute_domain=new6 project-domain=new3 project_domain=new2 user-domain=new5 user_domain=new4
+ Operations: monitor interval=60s (test2-monitor-interval-60s)
+ """
+ )
+ )
+
def testStonithFenceConfirm(self):
output, returnVal = pcs(temp_cib, "stonith fence blah blah")
assert returnVal == 1
--
2.13.6