|
|
15f218 |
From 5921099626e3afde044027ed493bdee905db4415 Mon Sep 17 00:00:00 2001
|
|
|
15f218 |
From: Tomas Jelinek <tojeline@redhat.com>
|
|
|
15f218 |
Date: Thu, 21 Jul 2016 13:58:41 +0200
|
|
|
15f218 |
Subject: [PATCH] fix filter by property name in "pcs property show"
|
|
|
15f218 |
|
|
|
15f218 |
---
|
|
|
15f218 |
pcs/prop.py | 14 +--
|
|
|
15f218 |
pcs/test/test_properties.py | 263 ++++++++++++++++++++++++++++++++++----------
|
|
|
15f218 |
pcs/utils.py | 13 ++-
|
|
|
15f218 |
3 files changed, 223 insertions(+), 67 deletions(-)
|
|
|
15f218 |
|
|
|
15f218 |
diff --git a/pcs/prop.py b/pcs/prop.py
|
|
|
15f218 |
index 36eba60..92a953c 100644
|
|
|
15f218 |
--- a/pcs/prop.py
|
|
|
15f218 |
+++ b/pcs/prop.py
|
|
|
15f218 |
@@ -100,9 +100,7 @@ def unset_property(argv):
|
|
|
15f218 |
utils.replace_cib_configuration(cib_dom)
|
|
|
15f218 |
|
|
|
15f218 |
def list_property(argv):
|
|
|
15f218 |
- print_all = False
|
|
|
15f218 |
- if len(argv) == 0:
|
|
|
15f218 |
- print_all = True
|
|
|
15f218 |
+ print_all = len(argv) == 0
|
|
|
15f218 |
|
|
|
15f218 |
if "--all" in utils.pcs_options and "--defaults" in utils.pcs_options:
|
|
|
15f218 |
utils.err("you cannot specify both --all and --defaults")
|
|
|
15f218 |
@@ -124,13 +122,15 @@ def list_property(argv):
|
|
|
15f218 |
for prop,val in sorted(properties.items()):
|
|
|
15f218 |
print(" " + prop + ": " + val)
|
|
|
15f218 |
|
|
|
15f218 |
- node_attributes = utils.get_node_attributes()
|
|
|
15f218 |
+ node_attributes = utils.get_node_attributes(
|
|
|
15f218 |
+ filter_attr=(None if print_all else argv[0])
|
|
|
15f218 |
+ )
|
|
|
15f218 |
if node_attributes:
|
|
|
15f218 |
print("Node Attributes:")
|
|
|
15f218 |
- for node in sorted(node_attributes):
|
|
|
15f218 |
+ for node in sorted(node_attributes.keys()):
|
|
|
15f218 |
line_parts = [" " + node + ":"]
|
|
|
15f218 |
- for attr in node_attributes[node]:
|
|
|
15f218 |
- line_parts.append(attr)
|
|
|
15f218 |
+ for name, value in sorted(node_attributes[node].items()):
|
|
|
15f218 |
+ line_parts.append("{0}={1}".format(name, value))
|
|
|
15f218 |
print(" ".join(line_parts))
|
|
|
15f218 |
|
|
|
15f218 |
def get_default_properties():
|
|
|
15f218 |
diff --git a/pcs/test/test_properties.py b/pcs/test/test_properties.py
|
|
|
15f218 |
index 6cdd2e5..fbaf880 100644
|
|
|
15f218 |
--- a/pcs/test/test_properties.py
|
|
|
15f218 |
+++ b/pcs/test/test_properties.py
|
|
|
15f218 |
@@ -8,11 +8,15 @@ from __future__ import (
|
|
|
15f218 |
import shutil
|
|
|
15f218 |
import unittest
|
|
|
15f218 |
|
|
|
15f218 |
+from pcs.test.tools.assertions import AssertPcsMixin
|
|
|
15f218 |
from pcs.test.tools.misc import (
|
|
|
15f218 |
ac,
|
|
|
15f218 |
get_test_resource as rc,
|
|
|
15f218 |
)
|
|
|
15f218 |
-from pcs.test.tools.pcs_runner import pcs
|
|
|
15f218 |
+from pcs.test.tools.pcs_runner import (
|
|
|
15f218 |
+ pcs,
|
|
|
15f218 |
+ PcsRunner,
|
|
|
15f218 |
+)
|
|
|
15f218 |
|
|
|
15f218 |
from pcs import utils
|
|
|
15f218 |
|
|
|
15f218 |
@@ -66,61 +70,6 @@ class PropertyTest(unittest.TestCase):
|
|
|
15f218 |
assert "stonith-enabled: false" in output
|
|
|
15f218 |
assert output.startswith('Cluster Properties:\n batch-limit')
|
|
|
15f218 |
|
|
|
15f218 |
- def testNodeProperties(self):
|
|
|
15f218 |
- utils.usefile = True
|
|
|
15f218 |
- utils.filename = temp_cib
|
|
|
15f218 |
- o,r = utils.run(["cibadmin","-M", '--xml-text', '<nodes><node id="1" uname="rh7-1"><instance_attributes id="nodes-1"/></node><node id="2" uname="rh7-2"><instance_attributes id="nodes-2"/></node></nodes>'])
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r == 0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property set --node=rh7-1 IP=192.168.1.1")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property set --node=rh7-2 IP=192.168.2.2")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property")
|
|
|
15f218 |
- ac(o,"Cluster Properties:\nNode Attributes:\n rh7-1: IP=192.168.1.1\n rh7-2: IP=192.168.2.2\n")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property set --node=rh7-2 IP=")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property")
|
|
|
15f218 |
- ac(o,"Cluster Properties:\nNode Attributes:\n rh7-1: IP=192.168.1.1\n")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property set --node=rh7-1 IP=192.168.1.1")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property set --node=rh7-2 IP=192.168.2.2")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property")
|
|
|
15f218 |
- ac(o,"Cluster Properties:\nNode Attributes:\n rh7-1: IP=192.168.1.1\n rh7-2: IP=192.168.2.2\n")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property unset --node=rh7-1 IP")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property")
|
|
|
15f218 |
- ac(o,"Cluster Properties:\nNode Attributes:\n rh7-2: IP=192.168.2.2\n")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property unset --node=rh7-1 IP")
|
|
|
15f218 |
- ac(o,"Error: attribute: 'IP' doesn't exist for node: 'rh7-1'\n")
|
|
|
15f218 |
- assert r==2
|
|
|
15f218 |
-
|
|
|
15f218 |
- o,r = pcs("property unset --node=rh7-1 IP --force")
|
|
|
15f218 |
- ac(o,"")
|
|
|
15f218 |
- assert r==0
|
|
|
15f218 |
-
|
|
|
15f218 |
def testBadProperties(self):
|
|
|
15f218 |
o,r = pcs(temp_cib, "property set xxxx=zzzz")
|
|
|
15f218 |
self.assertEqual(r, 1)
|
|
|
15f218 |
@@ -329,3 +278,205 @@ class PropertyTest(unittest.TestCase):
|
|
|
15f218 |
default-resource-stickiness: 0.1
|
|
|
15f218 |
"""
|
|
|
15f218 |
)
|
|
|
15f218 |
+
|
|
|
15f218 |
+
|
|
|
15f218 |
+class NodePropertyTestBase(unittest.TestCase, AssertPcsMixin):
|
|
|
15f218 |
+ def setUp(self):
|
|
|
15f218 |
+ shutil.copy(empty_cib, temp_cib)
|
|
|
15f218 |
+ self.pcs_runner = PcsRunner(temp_cib)
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def fixture_nodes(self, nodes, attrs=None):
|
|
|
15f218 |
+ attrs = dict() if attrs is None else attrs
|
|
|
15f218 |
+ xml_lines = ['<nodes>']
|
|
|
15f218 |
+ for node_id, node_name in enumerate(nodes, 1):
|
|
|
15f218 |
+ xml_lines.extend([
|
|
|
15f218 |
+ '<node id="{0}" uname="{1}">'.format(node_id, node_name),
|
|
|
15f218 |
+ '<instance_attributes id="nodes-{0}">'.format(node_id),
|
|
|
15f218 |
+ ])
|
|
|
15f218 |
+ nv = '<nvpair id="nodes-{id}-{name}" name="{name}" value="{val}"/>'
|
|
|
15f218 |
+ for name, value in attrs.get(node_name, dict()).items():
|
|
|
15f218 |
+ xml_lines.append(nv.format(id=node_id, name=name, val=value))
|
|
|
15f218 |
+ xml_lines.extend([
|
|
|
15f218 |
+ '</instance_attributes>',
|
|
|
15f218 |
+ '</node>'
|
|
|
15f218 |
+ ])
|
|
|
15f218 |
+ xml_lines.append('</nodes>')
|
|
|
15f218 |
+
|
|
|
15f218 |
+ utils.usefile = True
|
|
|
15f218 |
+ utils.filename = temp_cib
|
|
|
15f218 |
+ output, retval = utils.run([
|
|
|
15f218 |
+ "cibadmin", "--modify", '--xml-text', "\n".join(xml_lines)
|
|
|
15f218 |
+ ])
|
|
|
15f218 |
+ assert output == ""
|
|
|
15f218 |
+ assert retval == 0
|
|
|
15f218 |
+
|
|
|
15f218 |
+class NodePropertyShowTest(NodePropertyTestBase):
|
|
|
15f218 |
+ def test_empty(self):
|
|
|
15f218 |
+ self.fixture_nodes(["rh7-1", "rh7-2"])
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ "Cluster Properties:\n"
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_nonempty(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1
|
|
|
15f218 |
+ rh7-2: IP=192.168.1.2
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_multiple_per_node(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", "alias": "node1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", "alias": "node2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1 alias=node1
|
|
|
15f218 |
+ rh7-2: IP=192.168.1.2 alias=node2
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_name_filter_not_exists(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property show alias",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_name_filter_exists(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", "alias": "node1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property show alias",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: alias=node1
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+class NodePropertySetTest(NodePropertyTestBase):
|
|
|
15f218 |
+ def test_set_new(self):
|
|
|
15f218 |
+ self.fixture_nodes(["rh7-1", "rh7-2"])
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property set --node=rh7-1 IP=192.168.1.1"
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property set --node=rh7-2 IP=192.168.1.2"
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1
|
|
|
15f218 |
+ rh7-2: IP=192.168.1.2
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_set_existing(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property set --node=rh7-2 IP=192.168.2.2"
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1
|
|
|
15f218 |
+ rh7-2: IP=192.168.2.2
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_unset(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property set --node=rh7-2 IP="
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property",
|
|
|
15f218 |
+ """\
|
|
|
15f218 |
+Cluster Properties:
|
|
|
15f218 |
+Node Attributes:
|
|
|
15f218 |
+ rh7-1: IP=192.168.1.1
|
|
|
15f218 |
+"""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_unset_nonexisting(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_result(
|
|
|
15f218 |
+ "property unset --node=rh7-1 missing",
|
|
|
15f218 |
+ "Error: attribute: 'missing' doesn't exist for node: 'rh7-1'\n",
|
|
|
15f218 |
+ returncode=2
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+
|
|
|
15f218 |
+ def test_unset_nonexisting_forced(self):
|
|
|
15f218 |
+ self.fixture_nodes(
|
|
|
15f218 |
+ ["rh7-1", "rh7-2"],
|
|
|
15f218 |
+ {
|
|
|
15f218 |
+ "rh7-1": {"IP": "192.168.1.1", },
|
|
|
15f218 |
+ "rh7-2": {"IP": "192.168.1.2", },
|
|
|
15f218 |
+ }
|
|
|
15f218 |
+ )
|
|
|
15f218 |
+ self.assert_pcs_success(
|
|
|
15f218 |
+ "property unset --node=rh7-1 missing --force",
|
|
|
15f218 |
+ ""
|
|
|
15f218 |
+ )
|
|
|
15f218 |
diff --git a/pcs/utils.py b/pcs/utils.py
|
|
|
15f218 |
index 981a186..c7d1759 100644
|
|
|
15f218 |
--- a/pcs/utils.py
|
|
|
15f218 |
+++ b/pcs/utils.py
|
|
|
15f218 |
@@ -1659,19 +1659,24 @@ def set_unmanaged(resource):
|
|
|
15f218 |
"is-managed", "--meta", "--parameter-value", "false"]
|
|
|
15f218 |
return run(args)
|
|
|
15f218 |
|
|
|
15f218 |
-def get_node_attributes():
|
|
|
15f218 |
+def get_node_attributes(filter_node=None, filter_attr=None):
|
|
|
15f218 |
node_config = get_cib_xpath("//nodes")
|
|
|
15f218 |
- nas = {}
|
|
|
15f218 |
if (node_config == ""):
|
|
|
15f218 |
err("unable to get crm_config, is pacemaker running?")
|
|
|
15f218 |
dom = parseString(node_config).documentElement
|
|
|
15f218 |
+ nas = dict()
|
|
|
15f218 |
for node in dom.getElementsByTagName("node"):
|
|
|
15f218 |
nodename = node.getAttribute("uname")
|
|
|
15f218 |
+ if filter_node is not None and nodename != filter_node:
|
|
|
15f218 |
+ continue
|
|
|
15f218 |
for attributes in node.getElementsByTagName("instance_attributes"):
|
|
|
15f218 |
for nvp in attributes.getElementsByTagName("nvpair"):
|
|
|
15f218 |
+ attr_name = nvp.getAttribute("name")
|
|
|
15f218 |
+ if filter_attr is not None and attr_name != filter_attr:
|
|
|
15f218 |
+ continue
|
|
|
15f218 |
if nodename not in nas:
|
|
|
15f218 |
- nas[nodename] = []
|
|
|
15f218 |
- nas[nodename].append(nvp.getAttribute("name") + "=" + nvp.getAttribute("value"))
|
|
|
15f218 |
+ nas[nodename] = dict()
|
|
|
15f218 |
+ nas[nodename][attr_name] = nvp.getAttribute("value")
|
|
|
15f218 |
break
|
|
|
15f218 |
return nas
|
|
|
15f218 |
|
|
|
15f218 |
--
|
|
|
15f218 |
1.8.3.1
|
|
|
15f218 |
|