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