From b52c3ed9ec342b021357b915eaf6581f9f6a57d2 Mon Sep 17 00:00:00 2001 From: Ondrej Mular 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